richard.lin commited on
Commit
4fa86e6
·
1 Parent(s): 945cba1

fix: onnx export, consolidate the model onto one device.

Browse files
unidrive_vla_nusc_base_quantize_all.py CHANGED
@@ -429,11 +429,11 @@ def quantize_nvfp4(
429
  onnx_path = os.path.join(output_dir, "unidrive_vla_nvfp4.onnx")
430
  try:
431
  # Build a single sample input from the first calibration item.
432
- # export_to_onnx expects processed tensors, not raw messages metadata.
433
  sample_input = _process_calibration_batch(
434
  calibration_items[:1], processor, device
435
  )
436
- onnx_path = export_to_onnx(quantized_model, sample_input, onnx_path)
437
  except Exception as e:
438
  print(f" [WARN] ONNX export failed: {e}")
439
  print(f" The quantized PyTorch model is still saved at: {output_path}.")
@@ -473,24 +473,22 @@ def export_to_onnx(
473
  # Use the first calibration sample as dummy input
474
  sample_input = calibration_inputs[0]
475
 
476
- # --- Consolidate the model onto CPU before tracing. ---
477
- # torch.onnx.export(dynamo=False) traces via torch.jit. Tracing on GPU works
478
- # for the forward, but the bf16 weights + trace activations don't fit in
479
- # small-VRAM cards, and jit-trace of a model carrying accelerate hooks is
480
- # unreliable. Consolidating onto one device avoids both. CPU is used because
481
- # the NVFP4 ONNX export path is device-agnostic —
482
- # configure_linear_module_onnx_quantizers only flags quantizers to emit graph
483
- # nodes (no cuda kernels), and modelopt's own get_onnx_bytes_and_metadata
484
- # disables cuda autocast for fp4 models — so tracing on CPU yields the same
485
- # ONNX graph. (The model is loaded single-device now, but we still strip any
486
- # residual accelerate hooks defensively and move to CPU explicitly.)
487
  try:
488
  from accelerate.hooks import remove_hook_from_module
489
  if hasattr(model, "hf_device_map"):
490
  remove_hook_from_module(model, recurse=True)
491
  except ImportError:
492
  pass # no accelerate -> model is already single-device
493
- export_device = torch.device("cpu")
 
 
 
 
494
  model.to(export_device)
495
  sample_input = {
496
  k: (v.to(export_device) if torch.is_tensor(v) else v)
 
429
  onnx_path = os.path.join(output_dir, "unidrive_vla_nvfp4.onnx")
430
  try:
431
  # Build a single sample input from the first calibration item.
432
+ # export_to_onnx expects a list of processed input dicts and uses [0].
433
  sample_input = _process_calibration_batch(
434
  calibration_items[:1], processor, device
435
  )
436
+ onnx_path = export_to_onnx(quantized_model, [sample_input], onnx_path)
437
  except Exception as e:
438
  print(f" [WARN] ONNX export failed: {e}")
439
  print(f" The quantized PyTorch model is still saved at: {output_path}.")
 
473
  # Use the first calibration sample as dummy input
474
  sample_input = calibration_inputs[0]
475
 
476
+ # --- Consolidate the model onto one device before tracing. ---
477
+ # NVFP4 dynamic block-quantization requires amax to be a CUDA tensor, so
478
+ # tracing must run on GPU. On cards with limited VRAM this may OOM; however,
479
+ # the UniDriveVLA base model (~2.1B params) fits comfortably on an H20,
480
+ # so we default to cuda and only fall back to CPU if GPU tracing fails.
 
 
 
 
 
 
481
  try:
482
  from accelerate.hooks import remove_hook_from_module
483
  if hasattr(model, "hf_device_map"):
484
  remove_hook_from_module(model, recurse=True)
485
  except ImportError:
486
  pass # no accelerate -> model is already single-device
487
+
488
+ if torch.cuda.is_available():
489
+ export_device = torch.device("cuda")
490
+ else:
491
+ export_device = torch.device("cpu")
492
  model.to(export_device)
493
  sample_input = {
494
  k: (v.to(export_device) if torch.is_tensor(v) else v)