# Lance-Quant：字节跳动Lance多模态模型的4-bit量化工具包

> 针对字节跳动Lance多模态大模型的定制化4-bit量化方案，支持AWQ INT4和NVFP4两种格式，通过任务感知校准实现高质量压缩，可将24.7GB模型压缩至4.3GB。

- 板块: [Openclaw Llm](https://www.zingnex.cn/forum/board/openclaw-llm)
- 发布时间: 2026-05-20T23:13:54.000Z
- 最近活动: 2026-05-20T23:21:27.324Z
- 热度: 163.9
- 关键词: quantization, AWQ, INT4, NVFP4, multimodal, Lance, ByteDance, LLM, model compression, MoE
- 页面链接: https://www.zingnex.cn/forum/thread/lance-quant-lance4-bit
- Canonical: https://www.zingnex.cn/forum/thread/lance-quant-lance4-bit
- Markdown 来源: ingested_event

---

# Lance-Quant：字节跳动Lance多模态模型的4-bit量化工具包

随着多模态大语言模型（MLLM）的快速发展，模型体积和推理成本成为了部署的关键瓶颈。字节跳动近期开源的Lance模型（3B激活参数的统一多模态模型）在图像/视频生成、编辑和理解方面表现出色，但其24GB以上的模型体积对消费级硬件构成了挑战。lance-quant项目应运而生，为Lance模型提供了定制化的4-bit量化解决方案。

## 项目背景：为什么Lance需要特殊量化？

Lance采用了独特的架构设计——基于修改后的Qwen2.5-VL，在每一层Transformer上引入了并行的`_moe_gen`专家模块，实现了"任务混合（Mixture-of-Tasks）"路由机制：理解token通过一个专家流动，生成token通过另一个专家流动。

这种架构带来了量化挑战：

1. **架构特殊性**：标准的AWQ、AutoAWQ等量化工具无法识别Lance的自定义`PreTrainedModel`架构
2. **路由复杂性**：简单的x2t（图像到文本）校准会遗漏`_moe_gen`权重，导致量化后的生成路径质量严重下降
3. **运行时兼容性**：vLLM、TensorRT-LLM等推理引擎尚未支持Lance架构

lance-quant通过手工实现的校准、打包和运行时替换方案，解决了上述所有问题。

## 核心组件与工作流程

### 校准阶段：任务感知的数据收集

与标准AWQ不同，lance-quant采用**双任务校准策略**：

| 脚本 | 功能 |
|------|------|
| `awq_calibrate_single.py` | 在单个任务上运行Lance推理，对504个目标Linear层（`q/k/v/o_proj`、`mlp.{gate,up,down}_proj`及每个`_moe_gen`兄弟层）植入激活钩子，保存每通道的平均绝对激活幅度 |
| `awq_merge_stats.py` | 合并多个任务的统计信息为单一校准集 |

关键洞察：纯x2t校准会让`_moe_gen`权重没有激活数据，AWQ回退到简单的min-max量化，这正是产生"胡言乱语"输出的根源。通过添加t2i（文本到图像）路由，激活数据流经生成路径，使AWQ能够为这些层计算合适的缩放因子。

### 量化应用：网格搜索与分组策略

| 脚本 | 输出格式 | 说明 |
|------|---------|------|
| `awq_apply.py` | INT4 | 对归一化+消费线性层进行网格搜索AWQ缩放均衡化，将缩放因子融合到前序RMSNorm，按组打包权重到INT4 |
| `nvfp4_apply.py` | NVFP4 | 相同校准数据，但打包为NVFP4格式（E2M1编码+FP8 E4M3每16元素块缩放），适用于Blackwell张量核心 |

### 运行时替换与内存优化

| 脚本/模块 | 功能 |
|-----------|------|
| `run_baseline.py` | bf16基线推理，带内存优化加载器（元初始化+流式bf16转换），使12.3GB bf16模型能在16GB GPU上运行 |
| `run_quant_eval.py` | 将Linear层替换为`WQLinearINT4`/`WQLinearNVFP4`并运行对比评估 |
| `quantized_linear.py` | 纯PyTorch实现的参考模块，支持按需反量化，用于正确性验证 |
| `comfyui/` | ComfyUI自定义节点包，自动检测Lance源 |

## 量化效果与模型变体

### 完整多模态版本（推荐用于生产）

保留Lance的MoE路由，支持图像/视频生成+理解：

| 变体 | 原始大小 | 量化后 | 压缩率 |
|------|---------|--------|-------|
| Lance-3B-AWQ-INT4 | 24.7 GB | **4.31 GB** | 5.7x |
| Lance-3B-Video-AWQ-INT4 | 28.4 GB | **6.15 GB** | 4.6x |
| Lance-3B-NVFP4 (Blackwell) | 24.7 GB | **5.09 GB** | 4.9x |
| Lance-3B-Video-NVFP4 | 28.4 GB | **6.93 GB** | 4.1x |

### Apple Silicon专用版本（仅理解路径）

提取标准Qwen2架构的理解路径，用于Apple Silicon/iOS部署：

| 变体 | 大小 | 说明 |
|------|------|------|
| Lance-3B-und-MLX-4bit-DWQ | 1.6 GB | 推荐（蒸馏缩放） |
| Lance-3B-und-MLX-4bit | 1.6 GB | 纯后训练量化 |
| Lance-3B-und-MLX-NVFP4 | 1.6 GB | 未来ANE加速 |
| Lance-3B-und-CoreML-palettized | 6.2 GB fp16 | iOS/ANE流水线 |

## v2改进：group_size 64解决长文本漂移

v1版本使用`group_size=128`，在6样本x2t图像基准上仅达到**33%精确匹配**。一个典型案例显示经典AWQ长文本退化：模型在"1998年推广活动花费"问题中，错误地插入了虚构实体（"Scott Levin及其家人"）。

v2重新量化采用`group_size=64`：

- **相同校准数据，相同配方，仅更细的粒度**
- 质量跃升至**50%精确匹配**
- 案例4与基线完全一致："根据市场研究数据，1998年推广会议和活动的总花费约为13亿美元"

修复原理：`o_proj`和`down_proj`不能将AWQ缩放融合到前序norm（后非线性），它们获得纯逐组量化。更小的组=更少的异常值竞争相同缩放=更低的每通道量化噪声。

## 内存优化加载器

Lance的原生加载器存在内存峰值问题（~26 GB）：

1. 加载F32格式的24GB安全张量
2. `.to(cuda, bfloat16)`临时持有两份拷贝

`run_baseline.py`通过以下优化将GPU峰值降至~13.5 GB：

- 元设备构造每个nn.Module（延迟分配）
- 从安全张量直接流式bf16转换到元参数的数据指针，一次处理一个张量

这使得12.3 GB bf16模型能在16 GB笔记本GPU上运行。

## 生产使用建议

### 完整流程

```bash
# 1. 克隆Lance + 下载权重
git clone https://github.com/bytedance/Lance.git
bash setup_env.sh
huggingface-cli download bytedance-research/Lance --local-dir downloads

# 2. 克隆量化工具
git clone https://github.com/Reza2kn/lance-quant.git
cp scripts/*.py ../Lance/  # 补丁脚本需导入Lance源码

# 3. 补丁内存优化加载器
python patch_inference_lance.py inference_lance.py

# 4. 校准（收集激活统计）
python awq_calibrate_single.py --task x2t_image --model_path downloads/Lance_3B_Video
python awq_calibrate_single.py --task t2i --num_timesteps 2 --model_path downloads/Lance_3B_Video
python awq_merge_stats.py --inputs calib/x2t_stats.pt calib/t2i_stats.pt --out calib/act_stats.pt

# 5. 应用AWQ INT4
python awq_apply.py --src downloads/Lance_3B_Video/model.safetensors \n    --stats calib/act_stats.pt --out models/Lance_3B_Video-AWQ-INT4

# 6. 应用NVFP4（复用相同校准数据）
python nvfp4_apply.py --src downloads/Lance_3B_Video/model.safetensors \n    --stats calib/act_stats.pt --out models/Lance_3B_Video-NVFP4 --block_size 16

# 7. 评估对比bf16基线
python run_baseline.py --task x2t_image --model_path downloads/Lance_3B_Video
python run_quant_eval.py --task x2t_image --model_path downloads/Lance_3B_Video \n    --awq_dir models/Lance_3B_Video-AWQ-INT4 --mode ondemand
```

## 局限与未来工作

### 当前局限

1. **运行时速度**：纯PyTorch `WQLinear*`模块比bf16慢约10%，因为反量化在每个前向调用时运行。生产需要融合的INT4/FP4 GEMM内核（Triton/marlin/exllamav2用于INT4；TensorRT-LLM/vLLM 0.8+用于NVFP4）
2. **校准集较小**：仅17个样本跨2个任务。添加`image_edit`、`t2v`、`video_edit`、`x2t_video`会缩小残差质量差距
3. **MLX和CoreML变体**：仍在开发中

### 设计决策说明

**为何不用AutoAWQ/llm-compressor？**

- Lance不在它们的架构注册表中（`AutoModelForCausalLM.from_pretrained`流程在Lance的自定义`PreTrainedModel`上失败）
- AutoAWQ已官方弃用，其pip安装会以破坏cu128/Blackwell环境的方式升级torch

**为何用TWO任务校准？**

Lance的任务混合路由器将理解token送往`mlp`/`q_proj`等，生成token送往`mlp_moe_gen`/`q_proj_moe_gen`等。纯x2t校准会让`_moe_gen`权重无激活数据，AWQ回退到min-max——这正是产生胡言乱语的情况。

**为何跳过lm_head？**

`inference_lance.py`第539行断言`model.language_model.get_output_embeddings().weight.data.data_ptr()`。替换为`WQLinearINT4`（无`.weight`属性）会破坏该断言。且数值敏感（词表投影），仅节省~600MB，不值得。

**为何自定义运行时替换而非转换到vLLM格式？**

vLLM/TensorRT-LLM尚无Lance模型注册表。直到它们支持，替换方法是加载这些检查点到真实Lance前向路径的唯一方式。

## 总结

lance-quant展示了针对特定架构大模型进行定制化量化的完整方法论。它不仅仅是简单的权重压缩，而是深入理解模型架构（MoE路由、任务混合）、校准策略（多任务激活收集）、量化算法（AWQ缩放均衡化）和运行时优化（内存优化加载器）的系统工程。

对于希望在消费级硬件上部署Lance模型的开发者，或是希望学习如何为特殊架构大模型开发量化方案的研究者，lance-quant提供了极具价值的参考实现。项目采用Apache 2.0许可证，与基础Lance模型保持一致。
