写在前面
因为公司内部有一些大模型相关的使用需求,比如日常的文本处理、代码辅助、资料整理、文档总结这些。但有些内部文件不太适合直接丢到公网模型里,所以就想着干脆在公司现有的 GPU 服务器上先跑一套本地服务。机器配置如下:
| 项目 | 配置 |
|---|---|
| 内存 | 32GB DDR4 2933MHz × 4 共 128G |
| CPU | Intel Xeon Gold 6330 × 2 共 56C 112T |
| GPU | NVIDIA A100-SXM4-40GB × 2 共 80G |
对比模型
基于上述硬件配置,简单对比了以下两个由 Unsloth 量化的 Qwen3.6 GGUF 模型:
| 对比维度 | Qwen3.6-35B-A3B (Q6, MoE) | Qwen3.6-27B (Q8, Dense) |
|---|---|---|
| 架构类型 | 混合专家 (MoE) | 稠密模型 (Dense) |
| 激活参数 | 3B (动态激活) | 27B (全量激活) |
| 显存占用 | ~39 GB | ~56 GB |
| 推理速度 | ~120 Tokens/s | ~30 Tokens/s |
| 魔搭链接 | Qwen3.6-35B-A3B-GGUF | Qwen3.6-27B-GGUF |
| Hugging Face | Qwen3.6-35B-A3B-GGUF | Qwen3.6-27B-GGUF |
虽然很多人推崇 Qwen 的 27B 模型,但在当前部署环境和参数下,35B-A3B 的速度大约是 27B Dense 的 4 倍,于是最终选择了使用 Qwen3.6-35B-A3B。(Qwen3.5 的两个版本也有测试过,结果显示 35B-A3B 的速度大约是 27B Dense 的 2 倍。)
获取模型文件
访问魔搭社区的 Qwen3.6-35B-A3B-GGUF 仓库。在右侧 GGUF 区域下载 Q6_K_XL 版本的主模型文件,在顶部文件列表中单独下载 mmproj-BF16.gguf 多模态投影文件。
最终你将得到:Qwen3.6-35B-A3B-UD-Q6_K_XL.gguf 和 mmproj-BF16.gguf 两个文件
环境准备
一开始也考虑过使用 Ollama,但查了一些相关讨论后发现它对两个GGUF的拆分模型支持并不是太好,为了少踩坑,就直接选择了 llama.cpp。
确定使用 llama.cpp 之后,经过考虑还是因为系统原因选择了在 Docker 下跑。这台机器的系统是 CentOS 7.9,版本比较老,直接在宿主机上折腾依赖感觉风险有点大,还有可能影响其他正在运行的服务;但只为了部署模型去重装系统又有点太麻烦。
获取llama.cpp的镜像文件
以下所有操作都在root下执行,就不重复添加sudo了
# 使用以下命令拉取 `llama.cpp` 镜像
docker pull ghcr.io/ggml-org/llama.cpp:server-cuda
# 如果拉取速度过慢,可以尝试将 ghcr.io 替换为南京大学的ghcr.nju.edu.cn镜像站地址
docker pull ghcr.nju.edu.cn/ggml-org/llama.cpp:server-cuda创建模型存储目录
mkdir -p /opt/models/qwen36_35ba3b_q6/将前边的两个 GGUF 文件通过任意方式传输到此目录,接下来的步骤都在此目录下进行。
获取llama.cpp前端文件
部署过程中发现llama.cpp自带的web页面无法访问显示404,经过搜索 Github 里有人提到过这个问题。
解决方法是手动下载前端的文件并在后续挂载进容器内。
# 创建前端文件目录并进去
mkdir -p /opt/models/llama-ui && cd /opt/models/llama-ui
wget -O bundle.css https://huggingface.co/buckets/ggml-org/llama-ui/resolve/b9611/bundle.css
wget -O bundle.js https://huggingface.co/buckets/ggml-org/llama-ui/resolve/b9611/bundle.js
wget -O index.html https://huggingface.co/buckets/ggml-org/llama-ui/resolve/b9611/index.html
wget -O loading.html https://huggingface.co/buckets/ggml-org/llama-ui/resolve/b9611/loading.html创建 .env 文件
进入/opt/models/qwen36_35ba3b_q6/目录下创建 .env 文件,用于配置接口访问密钥:
LLAMA_API_KEY=your_api_key_here编写docker-compose.yml
进入/opt/models/qwen36_35ba3b_q6/,执行vi docker-compose.yml创建文件,将下面的内容写入文件。如果使用的是南京大学镜像站拉取镜像,请将第三行的ghcr.io替换为ghcr.nju.edu.cn。
services:
llama-cpp-server:
image: ghcr.io/ggml-org/llama.cpp:server-cuda
container_name: llama-cpp-server
ports:
- "8080:8080"
volumes:
- /opt/models/qwen36_35ba3b_q6/:/models
- /opt/models/llama-ui/:/ui:ro
runtime: nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=all
env_file:
- .env
command:
- -m
- /models/Qwen3.6-35B-A3B-UD-Q6_K_XL.gguf
- --mmproj
- /models/mmproj-BF16.gguf
- --alias
- qwen36_35ba3b_q6
- -ngl
- "999"
- -c
- "262144"
- --parallel
- "3"
- --cont-batching
- --flash-attn
- "on"
- --host
- 0.0.0.0
- --port
- "8080"
- -b
- "8192"
- -ub
- "1024"
- --path
- /ui
restart: unless-stoppedports中的8080:8080表示使用宿主机8080端口访问容器内的8080端口,如果被占用可改为8081:8080。volumes中第一个目录用于挂载模型文件,第二个目录用于挂载前面下载的 Web UI 文件。runtime: nvidia和NVIDIA_VISIBLE_DEVICES=all用于让容器调用宿主机上的 NVIDIA GPU。command部分是llama-server的启动参数,其中-m指定主模型,--mmproj指定多模态投影文件,-c 262144设置上下文长度,--parallel 3设置并发数量,--cont-batching和--flash-attn on用于提升推理性能。- 最后的
--path /ui是为了解决前面提到的 Web 页面 404 问题,让llama.cpp server使用手动挂载进去的前端文件。
启动容器
在 docker-compose.yml 所在目录执行以下代码启动。
docker compose up -d
# 如果是旧版Compose执行下方命令启动
docker-compose up -d使用以下代码查看启动情况:
# 使用以下代码查看容器状态
docker ps
# 查看日志确认模型是否正常加载:
docker logs -f llama-cpp-server
# 也可以使用nvidia-smi 查看显存占用情况
watch -n 1 nvidia-smi
如果启动正常,浏览器访问下面地址即可打开自带的聊天页面:
http://服务器IP:8080
打开自带的聊天页面后,按照下图填写前面设置的 API Key,填写完成后就可以直接测试对话效果。
Web UI 对话测试,页面中显示本次生成速度约为 126 tokens/s。
小结
到这里,这次本地部署基本就结束了。整体过程不算特别复杂,遇到的问题解决后 Web UI 和接口调用都可以正常使用。
如果后续想部署其他 GGUF 格式的模型,替换 docker-compose.yml 中 -m 后面的模型文件路径即可。如果部署的是纯文本模型,可以去掉 --mmproj 相关配置。
如果你在参考部署过程中遇到其他问题,也欢迎在评论区留言交流。



