Qwen3-VL-8B-Instruct 视觉分离(visual_only + normal + config_server)
测试标识:按顺序启动 三条 api_server 进程——config_server(配置与元数据;进程内部会启动 Redis 服务,并通过 --config_server_visual_redis_port(默认 6000)对外暴露)、visual_only(独立视觉 / ViT 侧)、normal(主 LLM,--visual_use_proxy_mode 经 config 访问视觉侧)。6000 不是本机另行安装的 redis-server,勿与系统包管理器里的 Redis 混为一谈。本流程验证 ViT 分离 + AFS 嵌入目录 的联调,并在 normal 就绪后须强制跑通 MMMU 验证集 mmmu_val(lmms_eval + openai_compatible,命令与 skills/test_model/qwen3-vl-8b-mmmu-val/SKILL.md 评测块一致;仅 api_server 拓扑 为本文的 visual 分离三进程)。
端口约定(固定,与脚本一致):
| 用途 | 端口 |
|---|---|
config_server |
8090(--config_server_port) |
Redis(由 config_server 内部启动并对外暴露) |
6000(--config_server_visual_redis_port;与系统独立安装的 Redis 无关) |
visual_only RPyC |
8091(--visual_rpyc_port) |
normal HTTP |
8089(--port) |
算力:visual_only 默认 1 张 GPU;normal 默认 --tp 2 → 2 张 GPU;三组进程不得争抢同一物理 GPU(脚本示例为 visual:0,LLM:6,7;实际以 nvidia-smi 选定)。
依赖
- Python 环境:与运行
lightllm.server.api_server的虚拟环境一致。 mmmu_val评测(必须):已安装lmms-eval,python3 -m lmms_eval可用(安装示例见skills/test_model/qwen3-vl-8b-mmmu-val/SKILL.md);未完成mmmu_val则本轮 不算通过。6000端口:由config_server在启动后内部拉起 Redis 并监听;无需、也不应依赖「事先在本机apt install redis-server并独占6000」——若系统已有其它服务占用6000,须释放或改--config_server_visual_redis_port(visual_only/normal须同步同一端口参数)。
日志目录(含 summary.txt)
- 选定
LOG_DIR,三条进程日志建议:"${LOG_DIR}/config_server.log"、"${LOG_DIR}/visual_only.log"、"${LOG_DIR}/normal.log"(nohup … >> … 2>&1 &)。 summary.txt:三条命令摘要、各端口 listen 情况、MODEL_DIR/AFS_IMAGE_EMBED_DIR最终取值;mmmu_val必记:OPENAI_API_BASE、完整lmms_eval命令、lmms_eval_console.log与lmms_eval_out路径、mmmu_acc(见下文「精度」);失败时写清原因与结论。lmms_eval_console.log(必须):lmms_eval终端输出(tee)。lmms_eval_out/(必须):--output_path下的*_results.json、*_samples_mmmu_val.jsonl(--log_samples生成样本日志)。
启动前检查
- 端口:本机
8090、6000、8091、8089未被其它进程占用(8090/6000在config_server启动后由其占用)。 config_server已就绪:8090与6000均已 LISTEN(表明 HTTP 配置面 与 内部 Redis 暴露面 已起来),再启动visual_only。MODEL_DIR:指向 Qwen3-VL-8B-Instruct;默认试跑/mtc/models/Qwen3-VL-8B-Instruct;不存在或加载失败时 向用户询问 本机路径。AFS_IMAGE_EMBED_DIR:--afs_image_embed_dir指向的目录须存在或可创建;默认试跑/mtc/afs/vit_embed_dir;不可用时 向用户询问。- 显卡:
visual_only与normal的CUDA_VISIBLE_DEVICES不得重叠;先nvidia-smi再export(不要写死示例卡号)。 CONFIG_SERVER_HOST:各进程--config_server_host须能访问config_server的 HTTP 服务。三进程同机时常见为0.0.0.0(与历史脚本一致);多机时改为 对端可达的 IP,并保证防火墙放行config_server端口(8090)、其内部 Redis 暴露端口(6000)、8091等。- 代理:每条
python(LightLLM) 前export http_proxy=、export https_proxy=(与仓库其它 acc 测试一致)。lmms_eval拉取lmms-lab/MMMU时若需经企业代理访问 Hugging Face,应在no_proxy已包含127.0.0.1的前提下恢复https_proxy(或等价镜像);否则易出现 HubConnectionError。仅当本机已有完整离线缓存且确认datasets可纯离线命中时,才可全程无代理。 lmms-eval:python3 -m lmms_eval --help可执行;否则无法完成必跑mmmu_val。
可变项
| 变量 | 含义 |
|---|---|
LOG_DIR |
本轮日志根目录。 |
MODEL_DIR |
--model_dir(三条中涉及模型的命令一致)。 |
AFS_IMAGE_EMBED_DIR |
--afs_image_embed_dir;visual_only 与 normal 须一致。 |
CONFIG_SERVER_HOST |
--config_server_host;同机试跑常用 0.0.0.0。 |
VISUAL_CUDA_DEVICES |
visual_only 的 CUDA_VISIBLE_DEVICES(1 张卡)。 |
LLM_CUDA_DEVICES |
normal 的 CUDA_VISIBLE_DEVICES(--tp 2 → 2 张卡)。 |
AFS_EMBED_CAPACITY |
--afs_embed_capacity;默认 250000;调试替换逻辑时可改为较小值(例如 100),见「调试提示」。 |
ORIG_HTTP_PROXY / ORIG_HTTPS_PROXY |
在清空代理启动 LightLLM 之前备份(见 lmms_eval 命令块),评测阶段恢复以便访问 Hugging Face Hub。 |
开跑前导出示例:
export ORIG_HTTP_PROXY="${http_proxy-}"
export ORIG_HTTPS_PROXY="${https_proxy-}"
export LOG_DIR='〈日志目录〉'
export MODEL_DIR='/mtc/models/Qwen3-VL-8B-Instruct'
export AFS_IMAGE_EMBED_DIR='/mtc/afs/vit_embed_dir'
export CONFIG_SERVER_HOST='0.0.0.0'
export AFS_EMBED_CAPACITY=250000
# export VISUAL_CUDA_DEVICES='0'
# export LLM_CUDA_DEVICES='6,7'
服务就绪判定
不要使用 HTTP health 作为唯一依据。依次确认:config_server 已占用 8090 与 6000(内部 Redis) → 8091(visual_only RPyC) → 8089(normal) 的 LISTEN 状态,并结合各 *.log;可约 每 20 秒 查看日志直至就绪或报错。
启动命令(须按顺序)
以下块前均须 export http_proxy=、export https_proxy=;生产式跑法请自行加 nohup 与 >> "${LOG_DIR}/….log" 2>&1 &。
1)config_server(最先)
python -m lightllm.server.api_server \
--run_mode config_server \
--config_server_host 0.0.0.0 \
--config_server_port 8090 \
--config_server_visual_redis_port 6000
若仅需绑定到 CONFIG_SERVER_HOST,将 --config_server_host 改为 "${CONFIG_SERVER_HOST}"(须与 visual_only / normal 中的 --config_server_host 指向同一可达地址)。
2)visual_only(config_server 已在 8090 / 6000 就绪后)
--visual_rpyc_port 8091 为 visual_only 模式必需,供其它服务调用本机视觉推理接口。
CUDA_VISIBLE_DEVICES="${VISUAL_CUDA_DEVICES}" python -m lightllm.server.api_server \
--run_mode visual_only \
--host 0.0.0.0 \
--config_server_host "${CONFIG_SERVER_HOST}" \
--config_server_port 8090 \
--config_server_visual_redis_port 6000 \
--model_dir "${MODEL_DIR}" \
--visual_dp 1 \
--visual_tp 1 \
--afs_image_embed_dir "${AFS_IMAGE_EMBED_DIR}" \
--afs_embed_capacity "${AFS_EMBED_CAPACITY}" \
--visual_rpyc_port 8091
--host 为 本进程监听地址;与 --config_server_host 含义不同:后者为 config_server 的可达地址。
3)normal(visual 就绪后)
CUDA_VISIBLE_DEVICES="${LLM_CUDA_DEVICES}" python -m lightllm.server.api_server \
--run_mode normal \
--model_dir "${MODEL_DIR}" \
--tp 2 \
--port 8089 \
--config_server_host "${CONFIG_SERVER_HOST}" \
--config_server_port 8090 \
--config_server_visual_redis_port 6000 \
--visual_dp 1 \
--afs_image_embed_dir "${AFS_IMAGE_EMBED_DIR}" \
--afs_embed_capacity "${AFS_EMBED_CAPACITY}" \
--visual_use_proxy_mode
mmmu_val 评测(normal 已监听 8089 后,必须执行)
在 config_server / visual_only / normal 均就绪、normal 仍占用 8089 时执行;关停任一服务前须跑完本节。评测流量只打 normal HTTP;OPENAI_API_BASE 须指向 http://〈可达主机〉:8089/v1(末尾含 /v1)。--model_args 中 model_version= 与三进程共用的 MODEL_DIR 须为同一权重目录。
export BIND_URL_HOST='127.0.0.1'
export PORT=8089
export OPENAI_API_BASE="http://${BIND_URL_HOST}:${PORT}/v1"
export OPENAI_API_KEY="${OPENAI_API_KEY:-lightllm123}"
export no_proxy=localhost,127.0.0.1,0.0.0.0,::1,${BIND_URL_HOST}
# 若启动 LightLLM 时清空了代理,此处恢复 Hub 代理(勿把 127.0.0.1 放进 ALL_PROXY)
export http_proxy="${ORIG_HTTP_PROXY:-}"
export https_proxy="${ORIG_HTTPS_PROXY:-}"
export LOG_DIR='〈与上文同一日志目录〉'
export MODEL_DIR='/mtc/models/Qwen3-VL-8B-Instruct'
mkdir -p "${LOG_DIR}/lmms_eval_out"
timeout 3600 python3 -m lmms_eval \
--model openai_compatible \
--model_args "model_version=${MODEL_DIR},tp=1" \
--tasks mmmu_val \
--batch_size 900 \
--log_samples \
--log_samples_suffix openai_compatible \
--output_path "${LOG_DIR}/lmms_eval_out" \
2>&1 | tee "${LOG_DIR}/lmms_eval_console.log"
说明:model_args 中的 tp=1 为 lmms_eval / openai_compatible 侧参数,与 normal 的 --tp 2 不同。若环境无 timeout,去掉 timeout 3600。仅本地冒烟可在命令中加 --limit;正式回归不得省略全量 mmmu_val。
精度(必须写入 summary.txt):最新 "${LOG_DIR}/lmms_eval_out"/*_results.json 中 results.mmmu_val["mmmu_acc,none"](0~1);无 jq 时打开 JSON 或对照 lmms_eval_console.log 末尾汇总表。
调试提示(可选)
- 将
AFS_EMBED_CAPACITY设为较小值(例如100)可更快触发 嵌入目录替换 / 淘汰 相关逻辑,便于缩短调试周期;正式回归再恢复250000(或业务约定值)。
执行约定
- 顺序:
config_server→visual_only→normal→mmmu_val(lmms_eval),前三步不可颠倒;mmmu_val未完成不得视为本轮通过。 mmmu_val:须在normal就绪 之后、关停normal之前 跑完(依赖8089与OPENAI_API_BASE)。model_version与MODEL_DIR必须一致。- 关停:
mmmu_val成功或失败均已落盘(日志与summary.txt)后,依次结束normal、visual_only、config_server;config_server退出后,其内部在6000上暴露的 Redis 随之停止,释放端口与 GPU。 - 失败:将摘要写入
summary.txt(含lmms_eval退出码、lmms_eval_console.log末尾),并在对话中给出关键日志与端口状态。