服务器大模型部署控制工具。通过 SSH 和 OpenAI 兼容 API 管理远程服务器(鲲鹏 920 + 4×昇腾 310P3)上的大模型部署(MindIE 昇腾推理栈)。
整机为华为 OptiXstar B896-U65(Ⅲ型) 10G-PON ONU 一体机服务器(SN 2106100120348E5R8000241,生产日期 2025-09)。
| 类别 | 配置 |
|---|---|
| CPU | 鲲鹏 920 3209(aarch64),24 核 |
| 内存 | 128G DDR4 |
| NPU | 4× 昇腾 310P3(2× Atlas 300I Duo,每卡双芯),各 ~44G HBM |
| 系统盘 | 2× 512G NVMe SSD(nvme0n1/nvme1n1),RAID1 镜像(两盘各存一份,可用容量=单盘,任一故障不停机) |
| 数据盘 | 2× 8TB HDD(HGST Ultrastar DC HC320,sda/sdb),LVM 卷组 mecvgdata |
| OS | ctyunos 2.0.1(aarch64),内核 4.19.90;Docker 25.0.3;NPU 驱动/CANN 25.2.0(/usr/local/Ascend) |
| 网络 | 192.168.133.2(SSH/API),经网关 192.168.133.1 NAT 上网;BMC 带外管理 192.168.133.250 |
NVMe ×2 (512G, RAID1 镜像, 状态 [UU])
├─ nvme0n1p1/p2 600M+1G /boot/efi + /boot(仅从 nvme0 挂载;
│ nvme0 故障时需在 BIOS 改引导盘)
├─ md126 (p3+p1) 8G swap(镜像,故 8G 而非 16G)
└─ md127 (p4+p2) 467G → / 系统盘,已用 120G / 空闲 316G
├─ ~19G Docker 镜像(MindIE 3.0.0 + portainer)
├─ 73G /models ← 模型权重【运行副本】(纯权重,
│ 无 .git;git 溯源信息在 /data 备份副本)
├─ 13G /usr(OS + CANN 系统组件)
└~ 7G /home + /root
HDD ×2 (8TB, 各自整盘做 LVM PV → 卷组 mecvgdata)
└─ mecvgdata-data 1T → /data 已用 88G:
├─ /data/models ← 模型权重【备份副本】
├─ /data/mindie_cache(pip/atc 缓存,容器重建加速)
└─ 厂商 k3s 活数据 ~1.3G(勿删)
VG 内还有 ~13.6TiB 未划分,可随时 lvextend 扩容
| 位置 | 介质 | 角色 |
|---|---|---|
/models/<模型> |
NVMe RAID1 | 运行副本——MindIE 服务从这里加载(deploy 配置指向此路径)。30B 模型启动 ~127s |
/data/models/<模型> |
HDD | 备份副本——迁移时已逐字节校验一致。平时不动它;NVMe 副本损坏/误删时用它恢复 |
- 新增/更新模型的流程:先下载到
/data/models(备份位),校验后cp -a到/models并修改 deploy 配置——两份都要有 - 恢复方法:
cp -a /data/models/<模型> /models/ - 判断哪份是权威:两份内容不一致时以最近校验过的一份为准,并尽快同步另一份
- 放 NVMe 的原因:权重加载从 HDD ~200MB/s 提到 NVMe 读取,30B 模型启动 263-295s → 127-137s(约 2 倍);7B 在两种盘上差异不大(~1 分钟)
/data 扩容策略:用到 ~70%(剩 ~260G)时在线扩,命令:
lvextend -r -L +1T /dev/mecvgdata/data(-r 自动同步扩文件系统,不停机)。
注:两块 HDD 在 LVM 内跨盘条带/线性,无镜像——单盘故障影响整个卷组;恢复手段为重新下载权重(可再生数据,风险可接受)。若日后要求可靠存储,可改两盘 RAID1(容量降至 8T,仍够用)。
凭据(SSH / BMC / 网关 telnet)见 config/config.yaml(已 gitignore,勿入库)。
双模型可切换(MindIE 3.0.0 容器,4×昇腾 310P3 TP4,同一时间运行一个):
| 模型 | 说明 |
|---|---|
qwen2.5-7b(默认) |
文本,压测 714 tok/s @ 并发 64 |
qwen3-vl |
30B-A3B MoE 视觉语言模型,支持图片/视频输入 |
OpenAI 兼容 API: http://192.168.133.2:1025/v1(无需鉴权)。
uv run python main.py chat "你好,介绍一下你自己" # 单轮对话
uv run python main.py health # 健康检查
uv run python main.py serve status # 服务状态
uv run python main.py serve start -m qwen3-vl # 启动指定模型(还有 stop/restart/logs)
uv run python main.py bench -c 64 -n 256 # 并发压测(当前面向 7B)- 地址: **https://192.168.133.2:9443**(自签证书,浏览器告警属正常,继续访问即可)
- 账号:
admin(密码见config/config.yaml的portainer节,登录后可在 UI 修改) - 用途: 查看容器状态/CPU 内存曲线/日志/进入控制台
⚠️ mindie 容器的启停请仍用本项目 CLI(main.py serve start|stop|restart -m ...)——mindie-server 是容器内 nohup 起的进程(容器主进程是 bash),在面板里 restart 容器只会得到一个空壳,服务不会自动拉起,且会丢失容器层已装的 vision 依赖- 镜像来源: Docker Hub 在此线路被墙,用的是 daocloud 镜像(
docker.m.daocloud.io);拉其他镜像同理,注意 arm64(--platform linux/arm64)
| 脚本 | 用途 |
|---|---|
src/deploy/serve_control.py |
MindIE 服务启停/状态/日志(SSH 远程执行) |
src/deploy/health_check.py |
API 健康检查 + 试跑一次对话 |
src/eval/bench.py |
并发压测(asyncio + httpx,统计吞吐/时延分位数) |
src/deploy/check_server.py |
服务器环境只读侦察 |
src/discovery/discover_models.py |
ModelScope 模型发现(兼容性判定引擎,配套 .claude/skills/model-scan 技能;服务器周日 03:11 自动跑) |
| 并发 | 请求 | 成功 | 吞吐 (out tok/s) | 时延 p50 (s) |
|---|---|---|---|---|
| 1 | 12 | 12/12 | 28.7 | 4.46 |
| 8 | 64 | 64/64 | 200.8 | 5.09 |
| 64 | 256 | 256/256 | 714.7 | 11.45 |
batch 64 验证通过:maxBatchSize=64 生效,吞吐随并发近线性扩展至 64 路。
依赖管理使用 uv(Python >3.11,<3.13)。
uv sync # 安装依赖
uv run pytest # 运行模型测试(服务未启动时自动 skip)
uv run ruff check . # lint
uv add <pkg> # 添加依赖| 文件 | 覆盖 |
|---|---|
test_api_contract.py |
OpenAI 兼容接口契约:模型列表/对话/usage 统计/max_tokens 截断/错误模型拒绝/流式输出/多轮上下文 |
test_capabilities.py |
常用能力:事实问答/算术/指令遵循/代码生成/翻译/总结/长文生成/中英混合 |
test_vision.py |
视觉:颜色识别(红蓝绿参数化)+ 图文结合推理——仅当部署的是 VL 模型时运行,否则自动 skip |
test_load_smoke.py |
8 路并发冒烟(完整压测用 main.py bench) |
模型自动检测:chat/health/bench 及全部测试用例默认跟随当前在跑的模型,切换部署后无需改参数(也可用 --model 显式指定)。压测结果落盘 results/。
凭据在 config/config.yaml(已 gitignore):服务器 SSH、BMC 带外管理地址与账号。