Document save/load architecture issues in RESEARCH_NOTES.md

Added critical analysis of current save/load implementation:

BROKEN COMPONENTS:
- Save node: Uses state_dict() - loses TensorQuantizer infrastructure
- Load node: Uses comfy.sd.load_model_weights() - creates wrapped modules
- Result: Quantized weights without quantization runtime

TECHNICAL DETAILS:
- Quantized models need TWO components saved:
  1. Model weights (quantized tensors)
  2. Quantizer infrastructure (TensorQuantizer layers, scales, zero-points)
- ModelOpt provides mto.save() and mto.restore() for this
- Current implementation loses quantizer state

SOLUTION APPROACHES:
- Option A: Use mto.save()/restore() with ComfyUI adapter
- Option B: Save modelopt_state separately, custom loader
- Option C: Export to TensorRT (bypasses PyTorch save/load)

COMFYUI INTEGRATION CHALLENGES:
- ModelOpt expects native PyTorch (torch.nn.Linear)
- ComfyUI provides wrapped modules (comfy.ops.Linear)
- Need bridge layer between these architectures
- May require custom ModelPatcher implementation

Updated next steps with critical save/load fix as blocking issue.
Added TensorRT export as alternative deployment path.
This commit is contained in:
Claude
2025-11-10 20:38:00 +00:00
parent f81d8d14d1
commit b0f16c8fa5
+127 -8
View File
@@ -219,6 +219,63 @@ def unwrap_comfy_ops(model):
**Side Effect**: Breaks tools expecting exact `torch.nn.Linear` type.
### Save/Load Architecture Issue
**The Problem**: Quantized models have **two components** that must be saved:
1. **Model Weights** (quantized tensors: INT8/FP8/INT4)
2. **Quantizer Infrastructure** (TensorQuantizer layers, scales, zero-points)
**Current Implementation (BROKEN)**:
```python
# Save node (nodes/quantizer.py:898)
state_dict = model.model.state_dict() # ❌ Only saves weights
torch.save(state_dict, path)
# Load node (nodes/loader.py:226)
sd = comfy.utils.load_torch_file(path)
model = comfy.sd.load_model_weights(sd, "") # ❌ Creates ComfyUI wrapped modules
```
**What Happens**:
- Save: TensorQuantizer state is lost (not part of standard state_dict)
- Load: Creates fresh ComfyUI model with wrapped `comfy.ops.Linear`
- Result: Quantized weights loaded into non-quantized architecture
- Outcome: Model may run but won't use quantization optimizations
**Correct Implementation (ModelOpt Functions)**:
```python
import modelopt.torch.opt as mto
# Save (preserves both weights AND quantizer state)
mto.save(model, "quantized_model.pth")
# Load (reconstructs quantizer infrastructure)
base_model = create_base_model() # Native PyTorch model
mto.restore(base_model, "quantized_model.pth")
```
**Alternative (Separate State)**:
```python
# Save
torch.save(mto.modelopt_state(model), "modelopt_state.pth")
torch.save(model.state_dict(), "weights.pth")
# Load
base_model = create_base_model()
mto.restore_from_modelopt_state(base_model, torch.load("modelopt_state.pth"))
base_model.load_state_dict(torch.load("weights.pth"))
```
**Additional Complexity for ComfyUI**:
- ModelOpt expects **native PyTorch** models (torch.nn.Linear)
- ComfyUI expects **wrapped modules** (comfy.ops.Linear)
- Need adapter layer to bridge these two worlds
- May require custom ModelPatcher that handles unwrapped quantized models
---
## ⚠️ KNOWN LIMITATIONS
@@ -230,11 +287,26 @@ def unwrap_comfy_ops(model):
- Solution: Module unwrapping (_unwrap_comfy_ops)
- Status: WORKING - 794 modules unwrapped, 2382 quantizers inserted
2. **No Verification of Quantization Quality**
2. **Save/Load Pipeline BROKEN** ❌ CRITICAL
- **Problem**: Current implementation loses quantizer infrastructure
- Save node uses `state_dict()` - only saves weights, not TensorQuantizers
- Load node uses `comfy.sd.load_model_weights()` - creates ComfyUI wrapped modules
- **Result**: Loaded model has quantized weights but no quantization runtime
- **Solution Required**: Use `mto.save()` and `mto.restore()` (ModelOpt functions)
- **Impact**: Saved quantized models cannot be loaded/used correctly
- **Status**: Needs complete rewrite of save/load nodes
3. **Model Type Mismatch in Loader**
- Quantization requires **native PyTorch** (`torch.nn.Linear/Conv2d`)
- Current loader creates **ComfyUI wrapped modules** (`comfy.ops.Linear`)
- Fundamental architecture incompatibility
- May need to bypass ComfyUI's model loading for quantized models
4. **No Verification of Quantization Quality**
- Even if quantization works, no validation that output quality is acceptable
- Need to add: PSNR, SSIM, or visual comparison tests
3. **No Support for Non-UNet Components**
5. **No Support for Non-UNet Components**
- VAE: Not quantizable (per ModelOpt design)
- CLIP: Not quantizable
- Only UNet backbone can be quantized
@@ -257,7 +329,23 @@ def unwrap_comfy_ops(model):
## 🎯 NEXT STEPS
### Immediate Testing (Current Priority)
### Critical Fixes Required
1. **Fix Save/Load Pipeline** ❌ BLOCKING
- **Current**: Uses `state_dict()` and `comfy.sd.load_model_weights()` - BROKEN
- **Required**: Implement `mto.save()` and `mto.restore()` functions
- **Challenges**:
- Need to create base model architecture for `mto.restore()`
- ModelOpt expects native PyTorch, ComfyUI provides wrapped modules
- May need custom model reconstruction logic
- Integration with ComfyUI's ModelPatcher system
- **Approach Options**:
- A) Save with `mto.save()`, load with `mto.restore()`, then wrap for ComfyUI
- B) Save modelopt_state separately, implement custom loader
- C) Export to TensorRT for deployment (bypasses load issues)
- **Priority**: HIGH - Without this, quantized models cannot be reused
### Immediate Testing (After Save/Load Fix)
1. **Complete Full Calibration Run** ✓ Ready
- Module unwrapping: ✅ Working
@@ -267,14 +355,45 @@ def unwrap_comfy_ops(model):
- Alternative: Reduce to 32-64 steps if needed
2. **Test Image Generation Quality**
- Generate test images with quantized model
- Generate test images with quantized model (in same session)
- Compare with unquantized baseline
- Document quality vs performance tradeoffs
- NOTE: Must test before saving due to save/load issues
3. **Save and Load Quantized Model**
- Test ModelOptSaveQuantized node
- Test ModelOptUNetLoader with saved model
- Verify end-to-end pipeline
3. **Test Save/Load Pipeline** (After implementing fix)
- Verify `mto.save()` preserves quantizer infrastructure
- Verify `mto.restore()` reconstructs quantizers correctly
- Test integration with ComfyUI's execution pipeline
- Verify end-to-end: quantize → save → load → inference
### Alternative Deployment Path: TensorRT Export
**Concept**: Instead of save/load within PyTorch, export to TensorRT for optimized inference.
**Advantages**:
- Bypasses save/load compatibility issues entirely
- Maximum performance (TensorRT optimizations)
- Production-ready deployment path
- Officially supported by NVIDIA
**Implementation**:
```python
# After quantization and calibration
import modelopt.torch.export as mte
mte.export_to_tensorrt(
model,
export_path="model.trt",
input_shapes={"latent": (1, 4, 128, 128), "timestep": (1,), ...}
)
```
**Challenges**:
- TensorRT integration with ComfyUI workflow
- Need TensorRT runtime in ComfyUI
- Input/output handling for dynamic shapes
- May require separate TRT loader node
**Priority**: MEDIUM - Good long-term solution, but needs research
### Future Improvements