Skip to content

fix(offload): move get_attr CPU FakeTensors to CUDA for model_cpu_offload - #62

Closed
cennn wants to merge 5 commits into
mainfrom
fix/offload-getattr-device
Closed

fix(offload): move get_attr CPU FakeTensors to CUDA for model_cpu_offload#62
cennn wants to merge 5 commits into
mainfrom
fix/offload-getattr-device

Conversation

@cennn

@cennn cennn commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

_fix_graph_device_placement only fixed factory functions (torch.empty/zeros etc.) but missed get_attr FX nodes. When model_cpu_offload=True, _patch_cpu_offload_apply keeps model weights on CPU, so Dynamo-inlined get_attr nodes carry CPU example_value. During PiecewiseCompileInterpreter.run(), inputs are moved to CUDA but get_attr weights stay CPU → index_select(CUDA, CPU) device conflict in Inductor.

Fix: extend _fix_graph_device_placement to also move get_attr node meta["example_value"] from CPU to CUDA.

Context

Found while trying to run Gaga4 base model on 8x5090 (SM120) with model_cpu_offload. The model has extensive index_select with modality dispatching, which hit this device mismatch.

Test plan

  • Verify Gaga4 base model compiles with model_cpu_offload=True on 5090

cennn added 5 commits August 24, 2026 23:45
Three fixes for running gaga4 base model with model_cpu_offload:

1. _fix_graph_device_placement: move get_attr CPU FakeTensors to CUDA
   (weights stay CPU but compile needs CUDA FakeTensors)

2. offload(): recurse into object __dict__ to CPU-offload tensor
   attributes of non-tensor args (e.g. ModalityDispatcher.permute_mapping)

3. RemoveItemPass: accept any call_function user for placeholder-sourced
   .item() nodes, not just the SUPPORTED_OPS whitelist. This handles
   custom ops like athena.gaga4_fa_with_sink_cp that receive scalar args.
_fix_graph_device_placement moves placeholder example_values to CUDA
via .to(device), which drops nn.Parameter type from FakeTensor.
This caused _is_weight_node to classify all 1303 weights as inputs,
leading to _prepare_inputs moving 46 GiB to GPU and OOM.

Fix: check grapharg.source for ParamBufferSource (Dynamo provenance)
instead of relying on isinstance(val, nn.Parameter).
call_function nodes (custom ops like gaga4_mh_moe) can reference
weight/buffer placeholders. The scheduler only prefetches weights
for call_module nodes, so these remain on CPU causing device
mismatch. Fix: _ensure_cuda in call_function arg mapping.
@cennn

cennn commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by #64 which includes a broader device-placement fix (all node types, not just get_attr).

@cennn cennn closed this Aug 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant