跳至内容

Jetson AGX Thor 大模型部署实战一:以 MLC-LLM 部署 Qwen3-30B 为例

本文记录在 Jetson AGX Thor(JetPack 7.x / L4T r38.2)上使用 MLC-LLM 完成 Qwen3-30B-A3B-Instruct 部署的全过程,涵盖环境搭建、权重量化转换、运行时配置、CUDA 库编译及推理验证各环节。


〇、MLC-LLM 简介

MLC-LLM(Machine Learning Compilation for Large Language Models)是 Apache TVM 生态下的开源通用大模型部署方案。与传统推理框架依赖预编译运行时的思路不同,MLC-LLM 在部署时即时将模型编译为目标硬件原生代码,生成平台优化的动态库(.so / .dylib)。

在 Jetson 边缘计算场景下,MLC-LLM 具备以下核心优势:

特性说明
模型级编译通过 TVM Unity 进行全图级别优化,而非单算子调优,端到端延迟更优
通用量化支持 4bit 到 8bit 整数量化及 bf16/fp16 混合精度,可按层灵活配置
统一工具链一个 mlc_llm 命令覆盖完整流程:convert_weightgen_configcompilechat / serve
全平台部署同一份模型描述可目标到 CUDA(Jetson / 独显)、ROCm、Vulkan、Metal、WebGPU
OpenAI 兼容 API内置 mlc_llm serve 直接提供 /v1/chat/completions 接口,将大多数基于 OpenAI 的上层应用无缝接入
GPU-poor 友好支持张量并行、流水线并行和推测解码,最大限度降低硬件门槛

整体流程为:拉取官方容器 → 下载模型权重 → 量化转换 → 生成配置 → 编译 CUDA 优化库 → 通过 CLI 对话或 HTTP 服务部署。以下章节将按步骤在 Jetson AGX Thor 上走通全流程。


一、前置说明

适配环境

项目版本要求
硬件平台Jetson AGX Thor(64GB 统一内存)
系统版本L4T r38.2(对应 JetPack 7.1/7.2)
部署框架NVIDIA 官方 MLC-LLM 容器镜像
目标模型Qwen3-30B-A3B-Instruct-2507(MoE 混合专家架构)
量化方案q4bf16_1(4bit 权重量化 + bf16 激活值,兼顾精度与显存占用)

工作目录约定

统一使用 /workspace 作为宿主机与容器的共享工作目录,所有模型、转换产物均存放在该目录下,避免路径映射混乱:

类型路径
原始模型/workspace/models/Qwen3-30B-A3B-Instruct-2507/
MLC 转换产物/workspace/models/mlc/Qwen3-30B-A3B-Instruct-2507-q4bf16_1/

MLC-LLM 优化能力边界

MLC-LLM 做什么(图级 + 宏观优化):

  • 计算图融合(算子融合、转置消除、死代码消除)
  • 量化格式选择(权重降精度、混合精度推理)
  • 静态显存规划(StaticPlanBlockMemory,编译期确定所有 buffer)
  • CUDA Graph 合并(减少 CPU→GPU 调度往返)
  • Flash Attention 等粗粒度算子替换
  • 张量并行 / 流水线并行策略

MLC-LLM 不做什么(算子级微观调优):

  • 不提供逐算子的 loop tiling factor 配置
  • 不提供 vectorization width 手工指定
  • 不提供 thread block 大小的逐层调整
  • 不训练 AutoTVM cost model 进行搜索

一句话:MLC-LLM 的定位是「编译系统」,把 HuggingFace 模型编译成能跑的可执行文件,顺便做好图级优化;算子内部的极致调优不在它的职责范围内。如果需要在 Jetson 上压榨每帧的 kernel 性能,应回退到 TVM AutoTVM / AutoScheduler 手动调优,或在 MLC 编译产物之外引入 TensorRT 等专用推理引擎。


二、环境准备

2.1 拉取 MLC 官方 Docker 镜像

官方标准拉取命令:

docker pull ghcr.io/nvidia-ai-iot/mlc:r38.2.arm64-sbsa-cu130-24.04

2.2 下载目标模型(ModelScope)

直接指定工作目录下载,避免默认缓存路径导致的容器访问失败问题:

# 提前创建模型目录
sudo mkdir -p /workspace/models

# ModelScope 下载模型到指定路径
modelscope download --model qwen/Qwen3-30B-A3B-Instruct-2507 \
  --local_dir /workspace/models/Qwen3-30B-A3B-Instruct-2507

已有缓存模型迁移

如果模型已提前下载到其他目录,执行以下命令迁移到工作目录:

sudo mv /path/to/your/downloaded/model/* \
  /workspace/models/Qwen3-30B-A3B-Instruct-2507/
sudo chmod -R 755 /workspace/models

三、启动 MLC 运行容器

所有 MLC 相关命令必须在容器内部执行,宿主机无对应工具。

3.1 启动命令

sudo docker run -it --rm --runtime nvidia \
  -v /workspace:/workspace \
  -p 6677:6677 \
  ghcr.io/nvidia-ai-iot/mlc:r38.2.arm64-sbsa-cu130-24.04

3.2 核心参数说明

参数作用
--runtime nvidia挂载 NVIDIA GPU 运行时,Jetson 平台必加,否则容器无法调用 GPU
-v /workspace:/workspace宿主机与容器目录映射,文件实时同步,容器删除不丢失数据
-p 6677:6677API 服务端口映射,后续可通过宿主机 IP:6677 调用大模型接口

3.3 启动验证

命令执行后,终端前缀变为 root@xxxx:/# 即为成功进入容器,后续所有操作均在该容器终端内执行。


四、模型权重量化转换

将 HuggingFace 格式的原始模型,转换并量化为 MLC 可识别的专用权重格式。

4.1 前置校验

先确认模型配置文件存在,避免路径错误:

ls /workspace/models/Qwen3-30B-A3B-Instruct-2507/config.json

正常输出文件路径即为校验通过。

4.2 转换命令

# 提前创建输出目录
mkdir -p /workspace/models/mlc/Qwen3-30B-A3B-Instruct-2507-q4bf16_1

# 执行权重量化转换
mlc_llm convert_weight \
  --quantization q4bf16_1 \
  --model-type qwen3_moe \
  --device cuda \
  --source-format huggingface-safetensor \
  -o /workspace/models/mlc/Qwen3-30B-A3B-Instruct-2507-q4bf16_1 \
  /workspace/models/Qwen3-30B-A3B-Instruct-2507/

4.3 成功判定标准

  • 过程中无 ERROR / Exception 级别的报错,仅打印 INFO 日志属于正常现象
  • 最终输出 Finish exporting all parameters 即为转换完成
  • 输出目录下生成 params_shard_*.bin 权重分片与 ndarray-cache.json 索引文件
  • 30B 级 MoE 模型转换预计耗时 5-15 分钟

五、生成模型运行配置

生成 MLC 推理所需的配置文件,同时针对边缘设备做显存与性能优化。

5.1 执行命令

mlc_llm gen_config \
  --quantization q4bf16_1 \
  --conv-template qwen2 \
  --context-window-size 32768 \
  --prefill-chunk-size 4096 \
  --max-batch-size 3 \
  --output /workspace/models/mlc/Qwen3-30B-A3B-Instruct-2507-q4bf16_1 \
  /workspace/models/Qwen3-30B-A3B-Instruct-2507/

5.2 核心优化参数说明

参数作用适配意义
--context-window-size 32768限制最大上下文为 32K模型原生支持 262K 上下文,限制后大幅降低显存占用,适配边缘设备
--prefill-chunk-size 4096预填充分块大小平衡长输入场景的处理性能与显存占用
--max-batch-size 3最大并发批次支持同时处理 3 个请求,兼顾并发能力与硬件负载

5.3 成功判定标准

  • 日志输出 Dumping configuration file to: .../mlc-chat-config.json
  • 输出目录下生成 mlc-chat-config.json 核心配置文件,同时自动复制 tokenizer 相关文件

六、编译 CUDA 优化模型库

预编译针对 CUDA 平台深度优化的模型运行库(.so 文件),大幅提升后续启动速度与推理性能。

6.1 执行命令

mlc_llm compile \
  --device cuda \
  --quantization q4bf16_1 \
  --model-type qwen3_moe \
  --opt="cublas_gemm=1;cudagraph=1" \
  -o /workspace/models/mlc/Qwen3-30B-A3B-Instruct-2507-q4bf16_1/Qwen3-30B-A3B-Instruct-2507-q4bf16_1-cuda.so \
  /workspace/models/mlc/Qwen3-30B-A3B-Instruct-2507-q4bf16_1/mlc-chat-config.json

6.2 优化参数说明

参数作用
--opt="cublas_gemm=1"启用 cuBLAS 矩阵乘法加速,提升算子计算性能
--opt="cudagraph=1"启用 CUDA Graph 优化,减少 kernel 启动开销,提升生成速度

6.3 成功判定标准

  • 无报错完成编译,输出目录下生成对应 .so 模型库文件
  • 30B 级模型编译预计耗时 3-10 分钟

七、功能验证

7.1 交互式对话验证

直接启动命令行对话界面,快速验证模型可用性:

mlc_llm chat --device cuda \
  --model-lib /workspace/models/mlc/Qwen3-30B-A3B-Instruct-2507-q4bf16_1/Qwen3-30B-A3B-Instruct-2507-q4bf16_1-cuda.so \
  /workspace/models/mlc/Qwen3-30B-A3B-Instruct-2507-q4bf16_1

若未提前编译模型库,首次启动会自动触发 JIT 实时编译,完成后自动进入对话界面。

7.2 OpenAI 兼容 API 服务启动

启动 HTTP 服务,对外提供兼容 OpenAI 规范的接口,适配上层应用接入:

mlc_llm serve /workspace/models/mlc/Qwen3-30B-A3B-Instruct-2507-q4bf16_1 \
  --port 6677 \
  --host 0.0.0.0 \
  --device cuda \
  --model-lib /workspace/models/mlc/Qwen3-30B-A3B-Instruct-2507-q4bf16_1/Qwen3-30B-A3B-Instruct-2507-q4bf16_1-cuda.so \
  --overrides "max_num_sequence=1;max_total_seq_length=32768;context_window_size=32768;gpu_memory_utilization=0.3"

接口测试命令:

curl http://localhost:6677/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen3-30B-A3B-Instruct",
    "messages": [{"role": "user", "content": "你好,请介绍一下你自己"}],
    "temperature": 0.7,
    "max_tokens": 200
  }'

写在最后

走完整套 MLC-LLM 部署流程,有几点感受想和读者分享:

  1. MLC-LLM 的根基是 TVM 编译栈。 它建立在 Apache TVM 之上,核心思路是通过编译器技术将 LLM 适配到各种硬件后端,同一套模型描述可以目标到 CUDA、ROCm、Vulkan、Metal、WebGPU——这种「一次定义、到处编译」的理念让跨平台部署不再是一件痛苦的事。

  2. 上手门槛确实低。 CLI 一条命令、Python API 几行代码、REST server 直接启动,开箱即用的工具链让普通开发者无需深入编译器内部就能把 LLM 跑起来。客观地说,对大多数边缘端场景而言,MLC-LLM 确实是「最容易让一个 LLM 跑在边缘设备里」的方案之一。

  3. 但它不是追求__极致__性能的推理框架。 它的性能来自编译器自动化的图级优化和调度规则,而不是人工手写 kernel。这种自动化在很多场景下已经相当好了——Jetson 上 30B MoE 模型跑出可用速度本身就说明了问题——但和针对单一硬件手写汇编级 kernel 的方案(如 TensorRT、手写 CUDA kernel)相比,每个平台上的性能上限确实会低一档。这不是缺点,而是取舍。

  4. 针对 Jetson AGX Thor 这个平台,已经够用了。 Thor 的硬件水准本身就很高,64GB 统一内存、Ampere 级 GPU 核心——对于机器人、智能边缘等不需要「抠每一帧算力」的场景,工程师的时间比芯片的峰值利用率更珍贵。MLC-LLM 的自动化路线在这里恰恰是务实的正确选择。

  5. 希望这篇指南对你有帮助。 愿你能在自己的硬件上顺利跑通大模型,愿每一段代码都编译通过,愿每一次推理都返回你想要的答案。祝部署愉快。

最后更新于