Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Qwen3-Omni Local Stack

本仓库是 Qwen3-OmniDGX Spark / NVIDIA GB10 上的本地部署包装层,实际推理后端使用 vLLM-Omni,外层提供:

  • 一个本地 HTTP wrapper 服务
  • 一个命令行客户端
  • 一套单机部署、清理、打包脚本
  • 两个可复用 skill

当前默认且唯一推荐的运行 profile 是:

  • gptq4 -> thomasip/Qwen3-Omni-30B-A3B-Instruct-GPTQ-4bit

当前验证通过的能力

已经在本机实际验证通过:

  • text -> text
  • text -> audio
  • image -> text
  • audio -> text
  • video -> text
  • audio + image + video -> audio

当前已知限制:

  • 混合输入请求 output_modalities=text,audio 时,HTTP 请求已经能成功返回,但稳定拿到的是 audiotext 可能为空。
  • awq4nvfp4bf16 都不属于当前可交付主线,不会进入最终 usable bundle。

架构

  1. vllm serve ... --omni 负责加载模型和三段式推理。
  2. FastAPI wrapper 负责接收本地文件上传,转成上游 OpenAI-compatible 请求。
  3. CLI 客户端只调用 wrapper,不直接调用 vLLM-Omni

端口:

  • 上游模型服务:127.0.0.1:8091
  • wrapper 服务:127.0.0.1:8000

目录说明

  • src/qwen_omni_stack/: Python wrapper 与 CLI
  • scripts/: 环境、启动、测试、清理、打包脚本
  • configs/: 单机单卡 stage config
  • skills/: 当前仓库自带 skill
  • patches/vllm-omni/: 本地 vllm-omni 兼容修复补丁
  • var/models/huggingface/hub/: 模型缓存目录

环境准备

初始化环境:

./scripts/bootstrap_env.sh

这个脚本会:

  • 创建 .venv
  • 安装 torch 2.9.1+cu130
  • 安装 vllm 0.16.0+cu130
  • clone vllm-omni
  • 自动应用 patches/vllm-omni/*.patch
  • 安装当前项目本身

模型缓存策略

当前仓库只保留可用模型:

  • thomasip/Qwen3-Omni-30B-A3B-Instruct-GPTQ-4bit

本地缓存路径默认是:

  • var/models/huggingface/hub

不再保留在当前项目里的失败路线模型:

  • Qwen/Qwen3-Omni-30B-A3B-Instruct
  • cyankiwi/Qwen3-Omni-30B-A3B-Instruct-AWQ-4bit
  • cybermotaz/Qwen3-Omni-30B-A3B-Instruct-NVFP4
  • var/models/nvfp4_compat

注意:

  • 这些失败路线配置文件仍保留在仓库里,主要用于历史诊断和对照,不属于当前推荐部署路径。

启动服务

首次初始化或缺环境时启动整栈:

./scripts/start_stack.sh

日常只启动现有 Omni 后台服务:

./scripts/start_runtime_services.sh

EMEET 前端以前台方式运行:

./scripts/run_emeet_frontend.sh

桌面陪伴 daemon 以前台方式运行:

./scripts/run_desktop_assistant.sh

纯语音常驻对话以前台方式运行:

./scripts/run_voice_chat.sh

纯语音一键重启并启动:

./scripts/restart_backend_and_run_voice_chat.sh

纯语音一键自检并启动:

./scripts/restart_backend_selfcheck_and_run_voice_chat.sh

分开启动:

./scripts/start_model_server.sh
./scripts/start_api_server.sh

说明:

  • start_stack.sh 现在默认优先复用现有 .venv,只有环境缺失时才会触发 bootstrap_env.sh
  • start_runtime_services.sh 永远不会重装环境,只会启动已有的模型服务和 wrapper
  • 桌面助手联调建议使用 start_runtime_services.sh,再单独启动 EMEET 侧前端和桌面陪伴 daemon

桌面陪伴常用命令:

cd /home/dgx/github/Qwen3-Omni
./scripts/restart_backend_selfcheck_and_run_voice_chat.sh

./.venv/bin/ai-desktop-assistant status
./.venv/bin/ai-desktop-assistant ask-desk --prompt '请描述当前桌面' --capture-frame
./.venv/bin/ai-desktop-assistant note --text '记一下,下午继续验证 PTZ 节流'
./.venv/bin/ai-desktop-assistant resume
./.venv/bin/ai-desktop-assistant summarize
./.venv/bin/ai-desktop-assistant clear-day --yes
./.venv/bin/ai-desktop-assistant voice-chat
./.venv/bin/ai-desktop-assistant voice-chat --input-mode vad

voice-chat 现在默认是 CapsLock 按住说话:

  • 短按 CapsLock 仍然保留普通大小写切换
  • 长按超过约 300ms 开始录音,松手后提交给 Omni
  • Omni 播报时,只有再次长按 CapsLock 才会打断当前回复
  • 如果你要回退到旧的 VAD 模式,用 --input-mode vad

推荐的一键真机启动方式:

cd /home/dgx/github/Qwen3-Omni
./scripts/restart_backend_selfcheck_and_run_voice_chat.sh

停止与重启:

./scripts/stop_model_server.sh
./scripts/restart_model_server.sh
./scripts/stop_api_server.sh
./scripts/restart_api_server.sh

检查是否 ready:

curl http://127.0.0.1:8091/v1/models
curl http://127.0.0.1:8000/readyz

CLI 使用方法

健康检查:

./.venv/bin/qwen-omni-client ping --server http://127.0.0.1:8000

纯文本输入,文本输出:

./.venv/bin/qwen-omni-client infer \
  --server http://127.0.0.1:8000 \
  --prompt '请用一句话介绍你自己。' \
  --output-modalities text

纯文本输入,音频输出:

./.venv/bin/qwen-omni-client infer \
  --server http://127.0.0.1:8000 \
  --prompt '请用一句简短的话介绍你自己,并朗读出来。' \
  --output-modalities audio \
  --save-audio /home/dgx/github/Qwen3-Omni/var/outputs/text_to_audio.wav

图片输入,文本输出:

./.venv/bin/qwen-omni-client infer \
  --server http://127.0.0.1:8000 \
  --prompt '请用一句话描述这张图片。' \
  --image /home/dgx/github/Qwen3-Omni/var/samples/cherry_blossom.jpg \
  --output-modalities text

音频输入,文本输出:

./.venv/bin/qwen-omni-client infer \
  --server http://127.0.0.1:8000 \
  --prompt '请转写并简要总结这段音频。' \
  --audio /home/dgx/github/Qwen3-Omni/var/samples/mary_had_lamb.ogg \
  --output-modalities text

视频输入,文本输出:

./.venv/bin/qwen-omni-client infer \
  --server http://127.0.0.1:8000 \
  --prompt '请用一句话描述这个视频。' \
  --video /home/dgx/github/Qwen3-Omni/var/samples/sample_demo_1.mp4 \
  --output-modalities text

混合输入,语音输出:

./.venv/bin/qwen-omni-client infer \
  --server http://127.0.0.1:8000 \
  --prompt 'Use all inputs and answer briefly, then generate speech.' \
  --audio /home/dgx/github/Qwen3-Omni/var/samples/mary_had_lamb.ogg \
  --image /home/dgx/github/Qwen3-Omni/var/samples/cherry_blossom.jpg \
  --video /home/dgx/github/Qwen3-Omni/var/samples/sample_demo_1.mp4 \
  --output-modalities text,audio \
  --save-audio /home/dgx/github/Qwen3-Omni/var/outputs/mixed_modalities.wav

样例素材

下载样例素材:

./scripts/download_sample_assets.sh

样例位置:

  • var/samples/cherry_blossom.jpg
  • var/samples/mary_had_lamb.ogg
  • var/samples/sample_demo_1.mp4

Smoke Test

运行全量 smoke test:

QWEN_OMNI_MODEL_PROFILE=gptq4 ./scripts/smoke_test_all_modalities.sh

它会顺序覆盖:

  • ping
  • text -> text
  • text -> audio
  • image -> text
  • audio -> text
  • video -> text
  • audio + image + video -> text,audio

说明:

  • 当前最后一项请求已经可以成功返回并保存音频,但文本字段不作为已验收能力。

模型清理

先做 dry-run:

./scripts/prune_model_cache.sh

真正执行隔离:

./scripts/stop_model_server.sh
./scripts/stop_api_server.sh
./scripts/prune_model_cache.sh --apply

行为说明:

  • 不可用模型不会直接 rm -rf
  • 会先移动到 var/trash/models/<timestamp>/
  • 同时写出 manifest.json

永久删除隔离模型:

./scripts/purge_quarantined_models.sh --apply

生成可用压缩包

生成 usable bundle:

./scripts/create_usable_bundle.sh

输出目录:

  • dist/Qwen3-Omni-gptq4-usable-<timestamp>.tar.zst
  • dist/Qwen3-Omni-gptq4-usable-<timestamp>.tar.zst.sha256
  • dist/Qwen3-Omni-gptq4-usable-<timestamp>.tar.zst.manifest.json

校验压缩包:

./scripts/verify_usable_bundle.sh dist/Qwen3-Omni-gptq4-usable-<timestamp>.tar.zst

压缩包只包含:

  • 当前仓库源码
  • 当前脚本
  • 配置
  • 测试
  • skills
  • vendor patch 文件
  • 样例素材
  • 当前唯一保留的 gptq4 模型缓存

不包含:

  • .venv
  • .vendor
  • 日志
  • pid
  • outputs
  • bf16
  • awq4
  • nvfp4

Skill 使用方式

当前仓库内自带两个 skill:

  • skills/qwen3-omni-multimodal-client
  • skills/qwen3-omni-bundle-manager

Skill 1: 多模态调用

先指定项目根目录:

export QWEN_OMNI_PROJECT_ROOT=/home/dgx/github/Qwen3-Omni

调用:

skills/qwen3-omni-multimodal-client/scripts/run_qwen3_omni_infer.sh ping
skills/qwen3-omni-multimodal-client/scripts/run_qwen3_omni_infer.sh infer --prompt '请用一句话介绍你自己。' --output-modalities text

Skill 2: 清理与打包

export QWEN_OMNI_PROJECT_ROOT=/home/dgx/github/Qwen3-Omni
skills/qwen3-omni-bundle-manager/scripts/prune_and_bundle.sh --dry-run
skills/qwen3-omni-bundle-manager/scripts/prune_and_bundle.sh --apply-prune
skills/qwen3-omni-bundle-manager/scripts/prune_and_bundle.sh --verify dist/Qwen3-Omni-gptq4-usable-<timestamp>.tar.zst

这些 skill 会同步发布到:

  • /home/dgx/github/my-skills-repo

GitHub 仓库

公开仓库目标:

  • https://github.com/redyuan43/Qwen3-Omni

本仓库不会提交:

  • 模型缓存
  • .venv
  • .vendor clone

为了复现当前可运行状态,仓库会提交:

  • patches/vllm-omni/*.patch
  • scripts/apply_vllm_omni_patches.sh

常见问题

502 Bad Gateway

  • 通常不是 wrapper 本身坏了,而是 8091 还没 ready
  • 先看:
curl http://127.0.0.1:8091/v1/models
curl http://127.0.0.1:8000/readyz

503 Service Unavailable

  • 说明 wrapper 已经起来,但上游模型服务还没准备好

混合输入返回了音频但没有文本

  • 这是当前已知限制
  • 当前阶段把它视为“部分成功”,不是完全失败

开发者说明

当前可运行状态依赖 vllm-omni 的本地兼容修复。

如果你更新了 .vendor/vllm-omni 本地改动,需要重新导出 patch:

./scripts/export_vllm_omni_patch.sh

然后在全新环境里由:

./scripts/bootstrap_env.sh

自动重放这些 patch。

About

Local DGX Spark deployment wrapper for Qwen3-Omni GPTQ4 with multimodal CLI, skills, and packaging scripts

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages