fix(profiling): patch sub-component methods at class level to prevent instance-isolation bug#13468
fix(profiling): patch sub-component methods at class level to prevent instance-isolation bug#13468Anai-Guo wants to merge 3 commits intohuggingface:mainfrom
Conversation
… instance-isolation bugs
| continue | ||
| setattr(component, method_name, annotate(method, label)) | ||
| if inspect.ismethod(method): | ||
| # Wrap the underlying function and patch at the class level so |
There was a problem hiding this comment.
Class-level patches should be avoided as they're not transient.
…() callable Class-level patches are saved before application and the function now returns a restore() callable that undoes them, making the patches explicitly transient. This addresses reviewer feedback that class-level patches without cleanup are non-transient.
Store the restore callable from annotate_pipeline() and call it at the end of run() so class-level method patches are cleaned up.
|
Thanks for the feedback @sayakpaul! Updated the PR to make the patches explicitly transient:
Class-level patches are still needed to fix the instance-isolation bug (the copy issue where |
Fixes #13462
Root cause
annotate_pipelinecalledsetattr(component, method_name, annotate(method, label))wheremethodis a bound method (retrieved viagetattr(component, method_name)). The resulting wrapper is a plain function that closes over the original bound method — and thus retains a hard reference to the original component instance.When a pipeline internally copies a sub-component (e.g.
audio_scheduler = copy.copy(self.scheduler)inpipeline_ltx2.py), the copy's instance__dict__inherits the wrapper. Callingaudio_scheduler.step(...)then silently dispatches toself.scheduler.step(...), sharing internal state (_step_index) between the two schedulers and producing index-out-of-bounds errors.Fix
Detect bound methods with
inspect.ismethodand patch at the class level instead:Because the wrapper is now set as a class attribute (an unbound function), Python's descriptor protocol re-binds it to whichever instance accesses it — including copies. Both the original scheduler and
audio_schedulerwill have properly isolatedstepcalls.Impact
examples/profiling/profiling_utils.pyonly (no production pipeline code changed)import inspectand a 5-lineif/elseguard