两天踩8个坑!MLC-LLM 交叉编译部署 Jetson 全记录,性能竟然没损失?
场景:Jetson Orin 8GB 部署 Qwen2.5-1.5B/3B 大模型前言:为什么我要折腾交叉编译?最近在搞边缘设备上的大模型部署,手头有一块 Jetson Orin 8GB 开发板。本来用 MLC-LLM 的 JIT(Just-In-Time)编译方案跑起来了,但每次启动都要在设备上编译 2 分钟,还得挂 swap 防 OOM,这谁受得了?而且网络不稳定的时候,第一次启动直接卡死在下载 HuggingFace 权重上…痛点有三:❌ 启动太慢(2 分钟编译)❌ 容易 OOM(8GB 内存编译不够用)❌ 离线不了(每次都要联网下权重)于是我想:能不能在 PC 上把模型编译好,直接拷贝到 Jetson 上跑?答案是:能!但过程踩了 8 个坑,花了我两天时间…先说结论(不看过程的可以直接跳最后)✅ 性能对比(实测数据)指标JIT 版交叉编译版评价1.5B 吞吐60 tok/s59 tok/s持平(误差 1%)3B 首次响应0.175s0.098s快 44%!启动时间~2 分钟秒级起飞内存占用编译时 8GB 爆满编译时 31GB 宽松安全离线部署❌✅自由核心发现:交叉编译不仅没损失性能,反而因为编译期参数优化,3B 模型的首次响应快了将近一半!正文开始:踩坑全记录坑 ①:import tvm 失败?缺个 pytest!场景:镜像构建到最后验证层,执行python -c "import tvm"直接炸了:ModuleNotFoundError: No module named 'pytest'我一查导入链,发现是这样的:tvm → tvm.rpc → tvm.rpc.testing → tvm.testing → tvm_ffi.testing → pytest原因:新一代 TVM 把 pytest 写进了顶层导入链,你的 venv 里没装 pytest,导入就失败。解决:Dockerfile 加一行:RUN uv pip install pytest教训:上游依赖变化快,看博客抄的命令可能已经过时了,对着源码核对最靠谱。坑 ②:tvm.support.libinfo() 消失了?继续构建,看到博客上说用这个命令检查 LLVM 支持情况:python-c"import tvm; print(tvm.support.libinfo().get('USE_LLVM'))"结果报错:AttributeError: module 'tvm.support' has no attribute 'libinfo'查源码:新版 TVM 已经把这个 API 删了!整个support模块只剩两个函数。正确姿势:用功能探测,不读配置字符串:python-c"import tvm; tvm.get_global_func('target.build.llvm'); print('OK')"这个函数只在 LLVM 存在时才会注册,存在 = 真正编进去了,比读字符串靠谱。坑 ③:构建时能用,运行时找不到库?构建验证全部通过,兴冲冲docker run起容器跑mlc_llm,结果:OSError: libfpA_intB_gemm.so: cannot open shared object file定位:构建时我用了export LD_LIBRARY_PATH=$(find ...),但这个环境变量只在那个RUN层里有效!docker run启动的容器根本继承不到。解决:固化到 ld 缓存(生成镜像的一部分):RUN find /opt/mlc-llm /opt/venv -name '*.so' -printf '%h\n' | sort -u \ /etc/ld.so.conf.d/mlc-llm.conf \ ldconfig⚠️ 注意:千万别把 CUDA stubs 目录加进来!否则运行时--gpus注入的真驱动会被 stub 顶掉,GPU 反而不可用了。坑 ④:【核心坑】undefined symbol: TVMFFIE