摩尔线程 MTT S80 本地跑大模型完整教程(llama.cpp + MUSA):从装驱动到 OpenAI 兼容 API
本文面向想在国产显卡上跑大模型、但没接触过 MUSA 生态的读者。
全部命令可直接复制,每一步都写清了「成功的标志」和「报错怎么办」。实测环境:Ubuntu 22.04 / 内核 5.15.x / MTT S80 16GB / MUSA SDK 4.3.0
〇、先说结论
| 项目 | 结果 |
|---|---|
| 能不能跑 | ✅能,而且能跑 21B 的 MoE 模型 |
| 用什么跑 | llama.cpp(自己编译 MUSA 后端) |
| 最快配置 | gpt-oss-20b(MXFP4)→15.16 tok/s,占 12.4 GB |
| 中文长文写作 | Qwen3-14B(Q4_0)→8.35 tok/s,占 12.1 GB |
| 最终形态 | systemd 服务 + OpenAI 兼容 API,开机自启 |
| 一句话评价 | 能跑大模型,但跑不快。瓶颈在软件生态,不在硬件 |
为什么是 llama.cpp?
vLLM / SGLang 在这张卡上没有可用版本(它们依赖的torch_musa只提供 MUSA 5.x 构建,
而5.x 官方只覆盖 S4000 / S5000)。Ollama 能跑,但它内部就是 llama.cpp,速度一样。
llama.cpp 是 C++ 原生实现、不经过 torch,只依赖 MUSA 运行时 ——
这是 S80 上唯一有性能优势的推理框架。
本文的前提:S80 已被系统正确识别。
如果你是虚拟机直通,还需要先处理 PCIe 直通和 16GB BAR 窗口重设,那是另一个话题。
一、准备工作
1.1 硬件
| 项 | 要求 |
|---|---|
| 显卡 | MTT S80(16GB) |
| 主板 | x86 台式机,有 PCIe x16 插槽 |
| 内存 | 32GB 以上(模型加载要占内存页缓存) |
| 硬盘 | 100GB 空余 |
| 电源 | 600W 以上 |
1.2 软件
- Ubuntu 22.04(⚠️ 官方只支持这个,别用别的版本)
1.3 ⚠️ 第一步:先确认卡能被识别
这一步不做,后面全白做。
sudomthreads-gmi✅ 成功:输出里有MTT S80、显存16384MiB、温度等信息。
❌ 报错对照:
| 报错 | 含义 |
|---|---|
command not found | 驱动没装 → 做第二章 |
Error: failed to initialize mtml | 忘了sudo;或卡没被识别 |
| 有命令但看不到 S80 | 卡未被识别 → 先解决驱动/直通问题 |
💡 工具名是
mthreads-gmi(g,不是 nvidia 那个 n)。mthreads-smi不存在。
二、安装 MUSA 驱动
驱动包叫musa_3.3.0-server_amd64.deb(约 161 MB),从摩尔线程开发者网站下载。
官方没有 apt 源,是手动拿 deb 装的,内核模块由 DKMS 现场编译。
sudoaptupdatesudoaptinstall-ydkmssudoaptinstall./musa_3.3.0-server_amd64.deb⚠️
./不能省 —— 否则 apt 会去网上仓库找,而不是装本地文件。
⚠️ 坑 1:四个版本号各不相同,别以为装错了
装完之后去核对版本,会发现四个数字全都不一样:
| 层面 | 版本 |
|---|---|
| deb 包名 | musa 3.3.0-server |
| DKMS 内核模块 | mtgpu/3.0.0 |
mthreads-gmi报告 | Driver Version: 3.0.0 |
musa_driver_version | 4.3.0 |
这四个都是对的,它们是不同层面的东西(包版本 / 内核模块 / 用户态 API 版本)。
别拿其中一个去"纠正"另一个,更别因此重装。
⚠️ 坑 2:一条看着吓人的无害报错
mtgpu: module verification failed: signature and/or required key missing - tainting kernel这只是"模块没签名、内核被标记污染"的提示,不影响任何功能。
⚠️ 坑 3:内核一定要 hold 住
官方只支持 Ubuntu 22.04 / kernel 5.15.x。不锁住的话,某次apt upgrade把内核推上去,
驱动就再也编不出来了。
先看当前内核:
uname-r假设输出5.15.0-105-generic,则:
sudoapt-mark hold linux-image-5.15.0-105-generic linux-headers-5.15.0-105-generic把版本号换成你自己
uname -r看到的那个。
✅ 成功标志:输出里有linux-image-xxx set on hold。
三、安装 MUSA SDK 4.3.0
驱动只是让系统认识这张卡;要编译/运行程序还需要 SDK(开发工具包)。
类比:装了显卡驱动能看视频,但要玩游戏还得装 DirectX。
3.1 下载与校验
从开发者网站下载musa_toolkits_4.3.0.tar.gz(约 1.93 GiB),建议先核对 sha256。
3.2 安装
tar-xzfmusa_toolkits_4.3.0.tar.gzcdmusa_toolkits_install&&sudobash./install.sh-isudoapt-getinstall-yg++ libstdc++-12-dev libelf-dev libnuma-dev✅ 成功标志:
mcc--version# mcc version 4.3.0
mcc是摩尔线程的编译器(底层是 clang 14),相当于 NVIDIA 的nvcc。
⚠️ 坑 4:SDK 里"缺"东西 —— 这决定了哪些路走不通
装完后用 cmake 探测会发现这些都是NOTFOUND:
mtgraph、mtjpeg(muDNN 相关)、mtml、mtrtc、OpenCLmuDNN 在 MUSA SDK 里是一个独立包(mudnn_rc3.1.x.tar.gz),
官方安装指南的 SDK 包结构是这样的:
├── mccl_rc2.1.x.tar.gz ├── mudnn_rc3.1.x.tar.gz ← 就是它 ├── musa_3.3.x-server_amd64.deb ← 驱动 └── musa_toolkits_rc4.3.x.tar.gz ← 工具链(我们装的)这意味着两条路本来就是断的:
GGML_MUSA_MUDNN_COPY—— muDNN 没装,且它只加速 F32/F16 的连续拷贝,量化权重根本不走这条路torch_musa(也就是 PyTorch)—— 缺libmudnn.so.3直接加载失败
📌 如果你后续想装 PyTorch,就得单独补 muDNN 这个包。
⚠️ 坑 5:千万别装 MUSA SDK 5.2.0
官方安装指南明写5.x 只覆盖 S4000 / S5000。4.3.x 就是 S80 的最后一站,装 5.x 白费工夫。
四、编译 llama.cpp
4.1 装依赖、拉源码
sudoaptinstall-ygitcmake build-essentialcd~gitclone https://github.com/ggml-org/llama.cppcdllama.cpp4.2 ★ 构建参数(重点只有一行)
cmake-Bbuild-graph\-DCMAKE_BUILD_TYPE=Release\-DGGML_MUSA=ON\-DGGML_MUSA_GRAPHS=ON cmake--buildbuild-graph -j"$(nproc)"| 参数 | 作用 |
|---|---|
-DGGML_MUSA=ON | 打开 MUSA 支持(不开就是纯 CPU 版) |
-DGGML_MUSA_GRAPHS=ON | ★ 关键开关 |
-j"$(nproc)" | 用满所有 CPU 核心 |
★-DGGML_MUSA_GRAPHS=ON是最容易漏的一项:
实测快 5.8% ~ 8.1%,而且速度抖动几乎归零(连续测三次数字完全一致)。
它默认是 OFF,藏在ggml/CMakeLists.txt里,不显式打开就不会编进去。
一个细节:
CMAKE_CXX_COMPILER用的是系统c++,不是 mcc。
mcc 只编译设备代码,宿主侧 C++ 走 g++。别把它指到 mcc 上。
⏱ 编译约需 20~40 分钟。
✅ 成功标志:[100%] Built target llama-server
五、下载模型
⚠️ 先说一个反直觉的事实
官方Qwen/Qwen3-14B-GGUF里没有 Q4_0。官方只发Q4_K_M/Q5/Q6/Q8。
想要 Q4_0,必须去第三方量化仓库。
实测可用的两个直链(已用 HEAD 请求验证 200 + 文件大小):
| 模型 | 仓库 | 大小 |
|---|---|---|
| Qwen3-14B Q4_0(中文写作) | unsloth/Qwen3-14B-GGUF | 8.0 GB |
| gpt-oss-20b MXFP4(结构化分析) | ggml-org/gpt-oss-20b-GGUF | 11.3 GB |
sudoaptinstall-yaria2mkdir-p/opt/models# 模型一:Qwen3-14B Q4_0 —— 8.0 GBsudoaria2c-x16-s16-d/opt/models-oQwen3-14B-Q4_0.gguf\"https://huggingface.co/unsloth/Qwen3-14B-GGUF/resolve/main/Qwen3-14B-Q4_0.gguf"# 模型二:gpt-oss-20b MXFP4 —— 11.3 GBsudoaria2c-x16-s16-d/opt/models-ogpt-oss-20b-MXFP4.gguf\"https://huggingface.co/ggml-org/gpt-oss-20b-GGUF/resolve/main/gpt-oss-20b-MXFP4.gguf"国内慢就把地址里的
huggingface.co换成hf-mirror.com(后面路径不用改)。
断了再跑一遍同样命令,aria2c 会自动续传。
5.1 ★ 量化格式:Q4_0 优于 Q4_K_M
| 文件名包含 | 选择 |
|---|---|
Q4_0 | ✅选这个 |
Q4_K_M | ❌ 看着"更高级",实测慢 21%~24% |
Q8_0/F16 | ❌ 太大,16GB 装不下 |
反直觉但有原因:llama.cpp 对
Q4_0有专门的优化 kernel。
5.2 ★ 模型选型:优先选 MoE
| 模型 | 速度 | 显存 |
|---|---|---|
| gpt-oss-20b(21B MoE) | 15.16 tok/s | 12.4 GB |
| Qwen3-8B(Q4_0) | 13.29 tok/s | 7.9 GB |
| Qwen3-14B(Q4_0) | 8.35 tok/s | 12.1 GB |
21B 的 MoE 比 8B 的 dense 还快 15%。
原因:MoE 每个 token 只读取**被激活的那几个"专家"**的权重,正好绕开了显存带宽瓶颈 —— 而带宽正是这张卡的短板。
六、先手动跑一次(确认链路通)
sudoenvLD_LIBRARY_PATH=/usr/local/musa/lib\"$HOME/llama.cpp/build-graph/bin/llama-cli"\-m/opt/models/Qwen3-14B-Q4_0.gguf\-ngl99-c4096\-p"介绍一下你自己"-n100| 参数 | 含义 |
|---|---|
LD_LIBRARY_PATH=... | 告诉程序去哪找 MUSA 库(必须写) |
-ngl 99 | 放到显卡上的层数,99 = 全部 |
-c 4096 | 上下文长度 |
✅ 成功:逐字往外蹦中文,末尾有速度统计。
| 现象 | 原因 |
|---|---|
CreatePlatform failed! | 必须sudo跑,非 root 一定失败 |
libmusart.so: cannot open shared object file | LD_LIBRARY_PATH漏了 |
| 只有 1~2 tok/s | 模型在跑 CPU,检查-ngl 99 |
七、做成 systemd 服务
7.1 配置文件
sudotee/etc/default/llama-server>/dev/null<<'EOF' LLAMA_MODEL=/opt/models/Qwen3-14B-Q4_0.gguf LLAMA_CTX=16384 LLAMA_NP=4 LLAMA_PORT=8080 EOF7.2 服务文件
sudotee/etc/systemd/system/llama-server.service>/dev/null<<'EOF' [Unit] Description=llama.cpp MUSA server After=network.target [Service] Type=simple User=root EnvironmentFile=/etc/default/llama-server Environment=LD_LIBRARY_PATH=/usr/local/musa/lib ExecStart=/home/<你的用户名>/llama.cpp/build-graph/bin/llama-server \ -m ${LLAMA_MODEL} -ngl 99 -c ${LLAMA_CTX} -np ${LLAMA_NP} \ --host 0.0.0.0 --port ${LLAMA_PORT} --no-warmup Restart=always [Install] WantedBy=multi-user.target EOF⚠️
/home/<你的用户名>/...要换成你真实的路径(echo $HOME看一下)。
| 设置 | 为什么 |
|---|---|
User=root | 必须—— MUSA 非 root 会失败 |
EnvironmentFile | 换模型不用动服务定义 |
Restart=always | 崩了自动拉起 |
--no-warmup | 跳过预热,就绪更快 |
7.3 启动
sudosystemctl daemon-reloadsudosystemctlenable--nowllama-server✅ 验证:
sudosystemctl status llama-server# active (running)curl-shttp://127.0.0.1:8080/health# {"status":"ok"}⚠️ 坑 6:-c是总上下文,不是每个并发的
服务里写-c 16384配-np 4,每个 slot 其实只有 4096。
查/v1/models看到n_ctx: 4096是对的,不是配置没生效。
⚠️ 坑 7:加载任何模型前,先清显存
MUSA 驱动释放显存不及时。杀掉进程后显存迟迟不回收,
不清理就直接加载新模型会 OOM,而且会污染后面所有测试。
sudotee/usr/local/bin/llama-vram-clean>/dev/null<<'EOF' #!/bin/bash systemctl stop llama-server 2>/dev/null sleep 2 pkill -x llama-server 2>/dev/null sleep 3 sync echo "显存已清理" EOFsudochmod+x /usr/local/bin/llama-vram-clean⚠️ 坑 8:但内存(RAM)千万不要清!
echo3>/proc/sys/vm/drop_caches# ❌ 绝对不要做显存和内存是两回事:
- 显存:驱动不释放,必须清(上面那个脚本)
- 内存:那 20 多 GB 是模型文件的页缓存,不能清
llama-server 用mmap加载模型,进程 RSS 只有 ~700 MB,模型数据都在页缓存里。
所以free看到used很高是正常的。
正是页缓存让第二次加载从 60 秒降到 16 秒。手动 drop 掉纯属倒退。
唯一要盯的是Swap,它被大量占用才说明真有内存压力。
八、调用 API
8.1 ⚠️ 中文有个坑
直接把 JSON 写在命令行里,中文会变乱码(服务端报ill-formed UTF-8 byte)。
正确做法:JSON 写进文件再发。
cat>/tmp/req.json<<'EOF' { "messages": [{"role": "user", "content": "用三句话介绍一下杭州"}], "max_tokens": 300, "chat_template_kwargs": {"enable_thinking": false} } EOFcurl-shttp://127.0.0.1:8080/v1/chat/completions\-H"Content-Type: application/json; charset=utf-8"\--data-binary @/tmp/req.json8.2 从别的机器调用
把127.0.0.1换成这台机器的 IP 即可(服务配的是--host 0.0.0.0)。
因为格式和 OpenAI 完全兼容,任何支持自定义 API 地址的客户端都能接
(Open WebUI / Cherry Studio / ChatBox / 自己写的脚本):
API 地址填http://<机器IP>:8080/v1,API Key随便填。
九、两个模型各有一个「必带参数」
9.1 用 gpt-oss 必须带reasoning_effort
它是推理模型,默认输出大量英文思考,不设这个参数会慢 6 倍。
| 值 | 适用 |
|---|---|
low | 纯写作(思考量极小) |
medium | 分析 / 计算 |
high | ❌ 别用,思考会吃光 token,正文为空 |
⚠️low是拿准确性换速度的:同一个财务计算题实测,low两次都把费用率算错
(算成 45% / 85%,正确答案 25%),medium算对。
写文章用low,要算数必须用medium。
9.2 用 Qwen3 必须关思考模式
Qwen3默认开启思考模式,会白白烧掉大量 token:
{"chat_template_kwargs":{"enable_thinking":false}}十、排错手册
10.1 三个必会命令
sudosystemctl status llama-server# 服务活着吗sudojournalctl-ullama-server-f# 实时看日志curl-shttp://127.0.0.1:8080/health# 健康检查10.2 ⚠️ 别信mthreads-gmi的显存读数
实测它会报出超过物理显存的数字(见过20102MiB(16384MiB)),
Free 值还会下溢到 2^64。这些是显示 bug,不是真泄漏。
判断 OOM 一律以日志里的
failed to allocate ...为准。
工具只信它的温度读数。
10.3 崩溃转储
MUSA 程序崩溃时会在工作目录落下core_*.mudmp文件,里面写明了是哪个 kernel、什么错误。
MUSA_ERROR_LAUNCH_TIMEOUT ... topk_moe_cuda<128, false><<<{1, 1, 1}, {32, 8, 1}>>>排查 kernel 类问题,这是第一手资料。
10.4 报错总表
| 报错 | 原因 | 怎么办 |
|---|---|---|
mthreads-gmi: command not found | 驱动没装 | 第二章 |
Error: failed to initialize mtml | 忘了 sudo / 卡没识别 | 加 sudo;仍不行先解决驱动 |
CreatePlatform failed! | 非 root 运行 | 必须 sudo |
libmusart.so: cannot open... | 库路径没设 | 加LD_LIBRARY_PATH=/usr/local/musa/lib |
undefined reference to musaLaunchKernel | 链接没加-lmusart | 编译参数加-lmusart |
failed to allocate ... | 真爆显存 | 换小模型,或先跑清显存脚本 |
| 只有 1~2 tok/s | 在跑 CPU | 检查-ngl 99 |
中文乱码ill-formed UTF-8 byte | 命令行编码 | JSON 写文件 +--data-binary @file |
| 输出一长串英文思考 | 没关思考模式 | 见 §9 |
附录 A:实测性能
| 模型 | 速度 | 显存 |
|---|---|---|
| gpt-oss-20b(21B MoE / MXFP4) | 15.16 tok/s | 12.4 GB |
| Qwen3-8B(Q4_0) | 13.29 tok/s | 7.9 GB |
| Qwen3-14B(Q4_0) | 8.35 tok/s | 12.1 GB |
| Qwen3-14B(Q4_K_M) | 6.76 tok/s | 10.6 GB |
和 RTX 4070 Ti Super 对比:
| MTT S80 | 4070 Ti Super | 比值 | |
|---|---|---|---|
| 显存带宽 | 392 GB/s(实测) | 672 GB/s | 0.58 |
| 14B Q4 实测 | 8.35 tok/s | 约 40~50 tok/s | 约 0.18 |
光看带宽只该慢 1.7 倍,实际慢了约 5 倍—— 多出来的约 3 倍是软件生态成熟度。
("约 5 倍"是取参考区间中点的近似值,区间两端算下来在 4.8~6.0 倍之间。)
但 16GB 没浪费:正是它让 21B 的 MoE 能全量进显存。
这台机器的定位是「能跑大模型,但跑不快」。
附录 B:常用命令
# 服务sudosystemctl status llama-serversudosystemctl restart llama-serversudojournalctl-ullama-server-f# 健康检查 / 看实际加载的模型curl-shttp://127.0.0.1:8080/healthcurl-shttp://127.0.0.1:8080/v1/models# 换模型前先清显存sudollama-vram-clean# GPU 状态(只信温度,别信显存)sudomthreads-gmi# 排查异常的最短路径# 1. 服务活着吗 systemctl is-active llama-server# 2. 加载的是我要的模型吗 curl /v1/models 或 pgrep -a llama-server# 3. 有 OOM 吗 journalctl -u llama-server | grep 'failed to allocate'# 4. 显存释放不掉 跑清显存脚本;实在不行重启机器免责声明
- 本文为个人折腾记录,硬件自购,与摩尔线程及任何厂商无利益关系
- 所有性能数据均为本机实测,不同环境 / 驱动版本会有差异,仅供参考
- 驱动与 SDK 请从官方渠道获取,注意其许可条款
- 文中结论仅代表当时那个版本的软硬件组合,后续版本可能已经改善