【LLM】Qwen3.5 35B A3B 单卡 RTX 3090 部署教程

1. 文档范围

本文记录在一台 Ubuntu 20.04.6、单张 RTX 3090 24GB 服务器上,使用 llama.cpp 部署 Qwen3.5-35B-A3B-Q3_K_M.gguf 多模态模型的可复现流程。

当前已验证的服务地址:http://192.168.10.104:10000/v1

当前服务提供文本和图像输入,OpenAI 兼容接口可直接被支持 OpenAI API 格式的客户端调用。

2. 已验证环境

项目 值
操作系统 Ubuntu 20.04.6 LTS
GPU NVIDIA GeForce RTX 3090 24GB
NVIDIA 驱动 535.86.05(部署过程中不升级)
CUDA Toolkit 11.4
CPU Intel Core i9-12900K
llama.cpp b10835
模型量化 Q3_K_M
上下文 131072 tokens(128K)
并发 1 路
API 端口 TCP 10000
图像投影 mmproj-F16.gguf,放在 CUDA0

显存选择依据

模型全量放入 GPU,KV cache 使用 q8_0,Flash Attention 开启,--parallel 1。服务启动后实测显存约 20.2GB,剩余约 4.0GB;128K 上下文和单路请求已经通过文本及真实图片请求验证。实际请求的图像尺寸、批量大小和输出长度会改变峰值显存,因此生产环境仍应保留降级方案:优先把上下文改为 96K,再改为 64K;同时保持 --parallel 1。

3. 目录约定

bash 复制代码
PROJECT=/home/xiaoying/project/qwen_vllm
MODEL_DIR=$PROJECT/models/Qwen3.5-35B-A3B-GGUF
LLAMA_DIR=$PROJECT/llama.cpp-b10835-source
BUILD_DIR=$LLAMA_DIR/build-native

最终模型文件:

text 复制代码
$MODEL_DIR/Qwen3.5-35B-A3B-Q3_K_M.gguf
$MODEL_DIR/mmproj-F16.gguf

4. 下载模型(国内网络)

优先使用 ModelScope。仓库名以实际发布页面为准;部署时使用的目录名为 Qwen3.5-35B-A3B-GGUF。

bash 复制代码
cd /home/xiaoying/project/qwen_vllm
python3 -m pip install -U modelscope
modelscope download \
  --model Qwen/Qwen3.5-35B-A3B-GGUF \
  --include 'Qwen3.5-35B-A3B-Q3_K_M.gguf' 'mmproj-F16.gguf' \
  --local_dir models/Qwen3.5-35B-A3B-GGUF

如果 ModelScope 页面更换了仓库命名,使用同一模型发布页下载这两个文件,再放到上述目录。不要跳过哈希校验,也不要用同名但来源不明的文件替换。

备用镜像方式(仅在网络策略允许时):

bash 复制代码
export HF_ENDPOINT=https://hf-mirror.com

5. 文件校验

部署所用文件的 SHA-256:

text 复制代码
Qwen3.5-35B-A3B-Q3_K_M.gguf
5607c8fcc8b04ada7d1a1152b9a5b6c1e67e6768232c16f6b03d9719d5ab1b2d

mmproj-F16.gguf
a516ab92e8240da4734d68352bdfba84c16e830ee40010b8fac80d69c77272ff

校验命令:

bash 复制代码
cd /home/xiaoying/project/qwen_vllm/models/Qwen3.5-35B-A3B-GGUF
sha256sum Qwen3.5-35B-A3B-Q3_K_M.gguf mmproj-F16.gguf

输出不一致时停止部署并重新下载;不要通过改名或强行启动绕过校验。

6. 编译 llama.cpp

编译时使用服务器已有 CUDA 11.4,不修改 NVIDIA 驱动。RTX 3090 属于 Ampere,CUDA 架构参数使用 86。

bash 复制代码
cd /home/xiaoying/project/qwen_vllm
git clone --depth 1 --branch b10835 https://github.com/ggml-org/llama.cpp.git llama.cpp-b10835-source
cd llama.cpp-b10835-source
cmake -S . -B build-native \
  -DGGML_CUDA=ON \
  -DCMAKE_CUDA_ARCHITECTURES=86 \
  -DCMAKE_BUILD_TYPE=Release
cmake --build build-native --config Release -j$(nproc)

如果服务器没有可用的 GitHub 连接,可在可联网机器下载 b10835 源码压缩包后传入服务器;源码版本必须保持 b10835。编译完成后确认:

bash 复制代码
/home/xiaoying/project/qwen_vllm/llama.cpp-b10835-source/build-native/bin/llama-server --version

若 CMake 报 CUDA 架构或编译器错误,先确认 nvidia-smi、nvcc --version 和 cmake --version,不要安装或升级驱动来"解决"编译问题。

7. systemd 服务

文件:/etc/systemd/system/qwen35-llama.service

ini 复制代码
[Unit]
Description=Qwen3.5 35B A3B llama.cpp API server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=xiaoying
Group=xiaoying
WorkingDirectory=/home/xiaoying/project/qwen_vllm/llama.cpp-b10835-source/build-native/bin
Environment=CUDA_VISIBLE_DEVICES=0
Environment=LD_LIBRARY_PATH=/home/xiaoying/project/qwen_vllm/llama.cpp-b10835-source/build-native/bin
ExecStart=/home/xiaoying/project/qwen_vllm/llama.cpp-b10835-source/build-native/bin/llama-server --model /home/xiaoying/project/qwen_vllm/models/Qwen3.5-35B-A3B-GGUF/Qwen3.5-35B-A3B-Q3_K_M.gguf --mmproj /home/xiaoying/project/qwen_vllm/models/Qwen3.5-35B-A3B-GGUF/mmproj-F16.gguf --mmproj-device CUDA0 --alias qwen3.5-35b-a3b --host 0.0.0.0 --port 10000 --ctx-size 131072 --parallel 1 --gpu-layers all --flash-attn on --cache-type-k q8_0 --cache-type-v q8_0 --batch-size 512 --ubatch-size 256 --threads 16 --threads-batch 32 --reasoning off --no-ui --metrics
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

应用配置并启动:

bash 复制代码
sudo systemctl daemon-reload
sudo systemctl enable --now qwen35-llama.service

本机当前要求为"关闭开机自动启动"时,使用:

bash 复制代码
sudo systemctl disable qwen35-llama.service
sudo systemctl start qwen35-llama.service

这会保持当前手动启动的服务运行,但重启机器后不会自动启动。

8. 防火墙与服务管理

bash 复制代码
sudo ufw allow 10000/tcp
sudo ufw delete allow 8000/tcp   # 仅当旧规则仍存在时执行
sudo ufw status numbered
bash 复制代码
sudo systemctl start qwen35-llama.service
sudo systemctl stop qwen35-llama.service
sudo systemctl restart qwen35-llama.service
systemctl --no-pager --full status qwen35-llama.service
journalctl -u qwen35-llama.service -n 200 --no-pager

9. 健康检查与 OpenAI 兼容接口

bash 复制代码
curl http://192.168.10.104:10000/health
curl http://192.168.10.104:10000/v1/models

文本请求:

bash 复制代码
curl http://192.168.10.104:10000/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "qwen3.5-35b-a3b",
    "messages": [{"role": "user", "content": "用一句话说明你已启动。"}],
    "temperature": 0.2,
    "max_tokens": 256
  }'

图像请求(OpenAI 多模态格式,图片内容使用 data URL):

python3 复制代码
import base64, json, requests

path = "./demo.jpg"
with open(path, "rb") as f:
    data = base64.b64encode(f.read()).decode()
payload = {
    "model": "qwen3.5-35b-a3b",
    "messages": [{"role": "user", "content": [
        {"type": "text", "text": "请描述这张图片。"},
        {"type": "image_url", "image_url": {
            "url": "data:image/jpeg;base64," + data
        }}
    ]}],
    "max_tokens": 256
}
r = requests.post(
    "http://192.168.10.104:10000/v1/chat/completions",
    json=payload, timeout=180)
r.raise_for_status()
print(r.json())

10. 故障排查

服务无法启动

bash 复制代码
systemctl status qwen35-llama.service
journalctl -u qwen35-llama.service -b --no-pager
nvidia-smi
ss -lntp | grep 10000

重点确认模型路径、mmproj 路径、CUDA_VISIBLE_DEVICES=0、端口是否被占用,以及当前用户是否能读取模型文件。

OOM 或图片请求失败

  1. 确认只有一个服务实例占用 GPU:pgrep -af llama-server。
  2. 保持 --parallel 1,先把 --ctx-size 131072 降为 98304,仍不足再降到 65536。
  3. 保持 KV cache 为 q8_0;不要在 24GB 卡上盲目增加并发或 batch。
  4. 图片编码有额外显存峰值,优先缩小图片分辨率并重试。

SIGILL / 非法指令

确认 CPU 与编译目标匹配;可移除过度激进的本机 CPU 优化后重新编译。GPU 侧不要把 RTX 3090 的 CUDA 架构写成 89 或 90。

CMake / CUDA 版本问题

本部署依赖现有驱动 535.86.05 和 CUDA 11.4。不要为了安装新版 Python 包或 CUDA Toolkit 自动升级驱动;先检查 which nvcc、nvcc --version、cmake --version,并确保编译和运行使用同一套 llama.cpp 构建产物。

首字慢

首次启动或首次出现新输入形状时,CUDA kernel/图像编码可能需要预热。保持 --parallel 1、--reasoning off,先发送短文本请求预热;实测稳定后的短文本请求首字约 0.54 秒,生成约 98 token/s,真实图片请求编码约 3.1 秒。

11. 当前验收结果

  • GET /health 返回 {"status":"ok"}。
  • /v1/models 显示 multimodal,上下文为 131072。
  • 文本请求成功。
  • 真实图片 Base64 请求成功并返回正确图片描述。
  • 端口 10000 已放行,旧端口 8000 规则已删除。
  • systemd 服务当前可运行,但已执行 disable,不随系统开机自动启动。
相关推荐
泰晶科技1 小时前
【智能手表晶振选型:小尺寸与低功耗如何兼得】
人工智能·笔记
吴佳浩1 小时前
构建企业级 DevOps 排错 Agent:从日志告警到自动化修复 PR
人工智能·agent·ai编程
机核研创社1 小时前
卫衣长袖长裤一套的自动化工序拆解:拉链侧袋、螺纹口、裤腰、卷边各交给谁做
人工智能·自动化
seowmt1 小时前
结构化数据和自然语言描述哪个更管用?答案分场景
人工智能·google·typescript·go语言·schema
海宇数据1 小时前
零信任架构实战:基于海宇车型识别精准构建自动化违章处理网关
运维·人工智能·架构·自动化
XMAIPC_Robot1 小时前
RK3588+CODESYS+RK182X AI 扩展机器人控制器解决方案|硬实时运动控制 + 大算力边缘 AI 融合实战
人工智能·机器人·rk3588+codesys·arm+codesys
陕西企来客1 小时前
NAP 信息统一治理:构建生成式 AI 时代企业 GEO 增长的坚实底座-企来客科技NAP方法论-企来客科技NAP信息治理实战解析
大数据·人工智能·科技
a努力。1 小时前
SpringBoot4迁移:Jackson3包名大变,注解别乱改
人工智能
SamChan901 小时前
PDF翻译时页眉页脚总在捣乱?跨页重复文本块的检测与过滤实测
人工智能·python·ai·pdf·wpf