Skip to content

Fridah/single gpu disk offload ptq#2008

Draft
Fridah-nv wants to merge 8 commits into
fridah/omniml-4947-mem-monitorfrom
fridah/single-gpu-disk-offload-ptq
Draft

Fridah/single gpu disk offload ptq#2008
Fridah-nv wants to merge 8 commits into
fridah/omniml-4947-mem-monitorfrom
fridah/single-gpu-disk-offload-ptq

Conversation

@Fridah-nv

Copy link
Copy Markdown
Contributor

What does this PR do?

Type of change: ?

Usage

# Add a code snippet demonstrating how to use this

Testing

Before your PR is "Ready for review"

Make sure you read and follow Contributor guidelines and your commits are signed (git commit -s -S).

Make sure you read and follow the Security Best Practices (e.g. avoiding hardcoded trust_remote_code=True, torch.load(..., weights_only=False), pickle, etc.).

  • Is this change backward compatible?: ✅ / ❌ / N/A
  • If you copied code from any other sources or added a new PIP dependency, did you follow guidance in CONTRIBUTING.md: ✅ / ❌ / N/A
  • Did you write any new necessary tests?: ✅ / ❌ / N/A
  • Did you update Changelog?: ✅ / ❌ / N/A
  • Did you get Claude approval on this PR?: ✅ / ❌ / N/A

Additional Information

Fridah-nv and others added 8 commits July 22, 2026 16:44
G1 (offload-aware export): fix _export_transformers_checkpoint to
materialize weights per decoder layer via enable_weight_access_and_writeback
before serializing, avoiding silent meta-tensor corruption when the model
was loaded with accelerate disk/CPU offload. Adds _has_accelerate_offload
detection and _process_quantized_modules_offloaded path. Adds meta-tensor
guard in _export_quantized_weight to surface silent corruption as loud error.

G2 (disk-offload CLI): --offload_folder, --max_gpu_memory_gb,
--max_cpu_memory_gb args wired through hf_ptq.py -> example_utils.get_model.
Validation guards prevent combining offload_folder with low_memory_mode or
use_seq_device_map.

G3 (CPU RSS check): psutil RSS verification after model load with disk
offload + max_cpu_memory_gb; warns if RSS > 110% of limit.

Supporting changes:
- NemotronHForCausalLM layer detection: check both backbone.layers and
  model.layers so the plugin works for both remote-code and native HF
  variants of the architecture.
- New recipe nvfp4_experts_only-kv_fp8_layerwise_offload.yaml: NVFP4
  W4A4 on experts, FP8 KV cache, layerwise calibration with
  calib_mutates_weights: false (disk-offload compatible).
- DSR1 BF16 fallback: _FP8BF16Fallback.matmul shim dequants block-scaled
  FP8 expert weights to BF16 for calibration forward passes when the
  kernels package is unavailable.
- Unit tests (6 CPU-only) and GPU integration tests (2 tiny-LLaMA) for
  the offload-aware export path.

Part of OMNIML-4947.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Fridah-nv <201670829+Fridah-nv@users.noreply.github.com>
Adds run scripts and worklog for end-to-end single-GPU disk-offload PTQ
validation on two production-scale models (OMNIML-4947):

- dsr1_run.sh: DSR1 642GB BF16 on 4 GPUs (fast demo, GPU-only).
- dsr1_single_gpu_run.sh: DSR1 single-GPU disk-offload (data collection).
- ultra550b_run.sh: Nemotron-Ultra 550B on single GPU with disk offload.
- ultra550b_4gpu_run.sh: Nemotron-Ultra 550B on 4 GPUs + CPU offload (demo).
- single_gpu_ptq_progress.md: worklog with run history, results, and
  known limitations.

DSR1 4-GPU run (Run 7) passed: 61 layers in 8m25s, 42 export shards in
235s, GPU peak 158-170 GiB, CPU RSS peak 629.82 GiB.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Fridah-nv <201670829+Fridah-nv@users.noreply.github.com>
Two fixes for the e2e validation run scripts:
1. Export PYTHONPATH=$REPO before python3 invocations so that the editable
   install's dev modelopt (0.46.0.dev) is found before system modelopt
   (0.21.0 at /usr/local/lib/python3.12/dist-packages) in subprocess
   sys.path. Root cause: pip install -e appends _EditableFinder to
   sys.meta_path (not prepends), so PathFinder finds /usr/local/modelopt
   first when the script dir is not the repo root.
2. --gpus now uses CSV format (0,1,2,3) matching the PR #2000 mem_monitor.py
   interface (--gpus takes a comma-separated string, not nargs="+").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Fridah-nv <201670829+Fridah-nv@users.noreply.github.com>
- Correct branch name (fridah/single-gpu-disk-offload-ptq)
- Record 4 commits landed this session
- Clarify mem_monitor.py source (cherry-picked from PR #2000, not hand-written)
- Document PYTHONPATH editable-install root cause and fix
- Note Python environment details (dev modelopt, transformers, torch versions)
- Mark Ultra 550B single-GPU run as in-progress (PID 2744499)
- Update --gpus format in DSR1 run command to CSV

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Fridah-nv <201670829+Fridah-nv@users.noreply.github.com>
_process_quantized_modules_offloaded previously only materialized decoder
layers.  For models like NemotronH-Ultra-550B where embed_tokens, norm_f,
and lm_head are also disk-offloaded, model.state_dict() returns meta
tensors for those modules.  After revert_weight_conversion_quant_aware
renames state_dict keys to hub-original names (backbone.*), transformers'
remove_tied_weights_from_state_dict calls model.get_parameter('backbone.*')
which fails because the model uses in-memory names (model.*).

Fix: after the decoder-layer loop, iterate non-decoder modules with
AlignDevicesHook and use enable_weight_access_and_writeback(writeback=False)
to collect their direct parameters.  The returned state dict is now
guaranteed to have no meta tensors.

Adds a unit test that verifies embed.weight is real (not meta) in the
returned state dict when only the embedding is disk-offloaded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Fridah-nv <201670829+Fridah-nv@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Fridah-nv <201670829+Fridah-nv@users.noreply.github.com>
Run completed successfully (PID 2875977, 2026-07-21):
- 15 safetensors shards, 33.2 min total wall time
- Peak GPU VRAM: 161.94 GB (single GB200)
- Peak CPU RSS: ~764 GiB
- Calibration: 8m41s (108 layers), Export: 322.6s (15 shards)
- Fix: non-decoder disk-offloaded tensors (embed, norm, lm_head) now
  materialized before state_dict rename to hub-original names, preventing
  the backbone AttributeError that crashed the first attempt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Fridah-nv <201670829+Fridah-nv@users.noreply.github.com>
Design for replacing the accumulate-all-then-save export pattern with a
streaming shard writer. Eliminates the 764 GiB peak CPU RSS that blocks
the 80 GB VRAM + 80 GB CPU RAM target from the original OMNIML-4947 ticket.

Key pieces:
- _StreamingShardWriter: buffers one shard at a time, flushes via safe_save_file
- _postprocess_single_tensor: per-tensor extraction from postprocess_state_dict
- _export_transformers_checkpoint_streaming: streaming path for offloaded models
- E2E test scripts: ultra550b_80gb_run.sh, dsr1_80gb_run.sh with 80 GB budget

Estimated peak: ~57 GB (Ultra 550B) and ~55 GB (DSR1), down from 764 GiB.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Fridah-nv <201670829+Fridah-nv@users.noreply.github.com>
@copy-pr-bot

copy-pr-bot Bot commented Jul 23, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 078dc0f4-5c42-49b2-a042-eb8c2c6ad208

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fridah/single-gpu-disk-offload-ptq

Comment @coderabbitai help to get the list of available commands.

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