vLLM-Omni 单卡部署 Stable Audio Open:文本生成音乐的离线推理与 OpenAI 兼容在线服务实战
【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni
导读
本文基于 vLLM-Omni 仓库中的官方配方(recipe)recipes/StabilityAI/Stable-Audio-Open.md,完整讲解如何在单张 GPU(已实测 NVIDIA RTX 4090 24GB 与 AMD MI300X 192GB)上部署 Stability AI 的stabilityai/stable-audio-open-1.0开源文本到音频(Text-to-Audio)扩散模型:既包含text_to_audio.py离线推理脚本的完整参数用法(含 TeaCache 加速),也覆盖通过vllm serve --omni启动的 OpenAI 兼容POST /v1/audio/generate在线服务。读完本文,你将掌握从模型授权下载、离线生成 10 秒 WAV、在线服务化,到输出采样率/时长校验与显存观测的一整套可复现实战方案,并理解其底层管线与 DiT 实现原理。
配方概览与适用场景
本配方的核心信息如下:
| 项目 | 内容 |
|---|---|
| 模型厂商 | Stability AI |
| 模型 | stabilityai/stable-audio-open-1.0 |
| 任务类型 | 文本到音频生成(音乐、音效、环境声) |
| 运行模式 | 离线推理 + 在线服务 |
| 维护方 | 社区(Community) |
适用场景:在单张 RTX 4090 24GB 显存上运行 Stable Audio Open,用于音乐或音效生成。配方给出了一个 10 秒的离线验证样例(开启 TeaCache 缓存加速),以及通过/v1/audio/generate端点对外提供服务的完整在线流程。该模型本身支持生成最长约 47 秒的 44.1 kHz 立体声音频,本配方验证的是 10 秒 WAV 输出。
前置准备:gated 模型授权与下载
stable-audio-open-1.0是 Hugging Face 上的门控(gated)模型,必须先在模型主页接受许可协议,才能下载权重。配方给出的下载流程如下:
hf auth login hf download stabilityai/stable-audio-open-1.0 \ --local-dir /path/to/stable-audio-open-1.0使用说明:
hf auth login会在本地写入 Hugging Face 访问令牌(等效于 README 中提到的huggingface-cli login,见 examples/offline_inference/text_to_audio/README.md);hf download将权重保存到本地目录,后续所有命令统一使用本地路径/path/to/stable-audio-open-1.0(也可直接使用仓库名stabilityai/stable-audio-open-1.0,由代码自动判断本地/远端来源,见 pipeline_stable_audio.py 中local_files_only = os.path.exists(model)的逻辑);- 在 CI/测试环境里,门控模型还需要提供
HF_TOKEN环境变量(见 tests/e2e/offline_inference/test_stable_audio_expansion.py 中的注释)。
离线推理:text_to_audio.py 全参数实战
离线示例脚本位于 examples/offline_inference/text_to_audio/text_to_audio.py,是一个针对文本到音频扩散模型的统一生成入口。配方中 RTX 4090 上的 10 秒验证命令(在仓库根目录执行):
python examples/offline_inference/text_to_audio/text_to_audio.py \ --model /path/to/stable-audio-open-1.0 \ --prompt "A gentle piano melody with soft room ambience" \ --negative-prompt "Low quality, distorted, noisy" \ --seed 42 \ --guidance-scale 7.0 \ --audio-length 10.0 \ --num-inference-steps 50 \ --cache-backend tea_cache \ --output examples/offline_inference/text_to_audio/stable_audio_10s.wav参数速查表
脚本通过argparse定义了大量参数,下面按类别整理(默认值以源码为准,见 text_to_audio.py):
核心生成参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--model | str | stabilityai/stable-audio-open-1.0 | 模型名或本地路径 |
--prompt | str | The sound of a hammer hitting a wooden surface. | 文本提示词 |
--negative-prompt | str | None(默认关闭) | CFG 负向提示词,推荐为 Stable Audio 显式指定 |
--seed | int | 42 | 随机种子,保证可复现 |
--guidance-scale | float | 7.0 | 无分类器引导(CFG)强度 |
--audio-start | float | 0.0 | 音频起始偏移(秒),映射为audio_start_in_s |
--audio-length | float | 10.0 | 音频时长(秒),映射为结束时间;stable-audio-open-1.0上限约 47 秒 |
--num-inference-steps | int | 100 | 扩散采样步数,步数越多质量越高、速度越慢 |
--num-waveforms | int | 1 | 每个提示词生成的波形数量 |
--sample-rate | int | 44100 | 输出采样率(Stable Audio 固定 44100 Hz) |
--extra-body | JSON | None | 以 JSON 对象传入模型专属参数,合并进sampling_params.extra_args,优先级高于同名 flag |
--output | str | stable_audio_output.wav | 输出 WAV 路径 |
缓存加速参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--cache-backend | str | None | 当前仅支持tea_cache(TeaCache 缓存加速);不传则无加速 |
--tea-cache-rel-l1-thresh | float | 0.2 | TeaCache 累积相对 L1 距离阈值 |
并行与显存优化参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--use-hsdp | flag | 关闭 | 启用 HSDP 权重分片(跨多卡降低单卡显存) |
--hsdp-shard-size | int | 1 | HSDP 分片使用的 GPU 数 |
--hsdp-replicate-size | int | 1 | HSDP 副本组数,默认 1 表示纯分片 |
--tensor-parallel-size | int | 1 | DiT 内部张量并行 GPU 数 |
--ulysses-degree/--ring-degree | int | 1 | Ulysses / Ring 序列并行 GPU 数 |
--ulysses-mode | str | strict | strict(要求整除)或advanced_uaa |
--cfg-parallel-size | int | 1(可选 1/2) | CFG 并行 GPU 数 |
--vae-patch-parallel-size | int | 1 | VAE patch/tile 并行(解码)GPU 数 |
--enable-cpu-offload | flag | 关闭 | 模型级 CPU offload,节省显存 |
--enable-layerwise-offload | flag | 关闭 | 逐层 CPU offload,进一步省显存 |
--enable-diffusion-pipeline-profiler | flag | 关闭 | 开启扩散管线剖析器,输出各阶段耗时 |
TeaCache 加速的底层原理
--cache-backend tea_cache是本配方验证过的关键加速手段。在源码层面,Stable Audio 的缓存支持由 vllm_omni/diffusion/cache/teacache/extractors.py 中的extract_stable_audio_context实现。其要点:
- 从第一个 transformer block 提取
modulated_input作为缓存判据(Stable Audio 使用标准 LayerNorm,且将"全局+时间"嵌入拼接到序列头部,因此首 token 携带时间步信号); - 当相邻两步的累积相对 L1 距离低于
rel_l1_thresh(脚本默认 0.2)时,跳过本轮 transformer blocks 前向,直接复用上一步的输出,从而减少 DiT 计算量; - 提取器将预处理、transformer 执行与后处理封装为
CacheContext,使 TeaCache hook 保持通用。MI300X 实测条目确认 TeaCache 以rel_l1_thresh=0.2运行。
提示:脚本内部将
--cache-backend tea_cache与--tea-cache-rel-l1-thresh组装为cache_config = {"rel_l1_thresh": ...}传给Omni(见 text_to_audio.py 第 237-240 行)。
离线推理的底层调用链
text_to_audio.py的调用链为:Omni.generate(prompt, OmniDiffusionSamplingParams)→ 扩散引擎调度 →StableAudioPipeline.forward。管线实现在 vllm_omni/diffusion/models/stable_audio/pipeline_stable_audio.py,核心流程如下:
- 文本编码:
T5TokenizerFast分词 →T5EncoderModel编码 →projection_model投影; - 时长编码:
encode_duration将audio_start_in_s/audio_end_in_s编码为seconds_start_hidden_states/seconds_end_hidden_states,与文本嵌入拼接成text_audio_duration_embeds与audio_duration_embeds; - 潜在噪声初始化:
prepare_latents按sample_size(默认 1024)生成随机 latent 并乘以调度器init_noise_sigma; - 去噪循环:
CosineDPMSolverMultistepScheduler迭代,DiT 预测噪声后执行 CFG 组合(noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)),StableAudioSchedulerWrapper专门处理最后一步零噪声采样; - VAE 解码:latent 经
AutoencoderOobleck解码为波形,再按waveform_start:waveform_end裁剪到请求时长。
其中 DiT 本体为 vllm_omni/diffusion/models/stable_audio/stable_audio_transformer.py 中的StableAudioDiTModel:24 层StableAudioDiTBlock(自注意力 + 交叉注意力 + SwiGLU FFN),隐藏维 1536(24 头 × 64 头维),输入/输出通道 64,交叉注意力采用 GQA(12 KV 头),线性层复用 vLLM 的ReplicatedLinear,注意力复用 vLLMAttention后端。管线类声明support_audio_output = True、audio_sample_rate = 44100,使默认 stage 元数据上报final_output_type="audio",multimodal_output携带采样率信息。
多卡与显存优化用法
除单卡命令外,README 与脚本还提供了降低单卡显存的用法。HSDP 分片示例:
python text_to_audio.py \ --model stabilityai/stable-audio-open-1.0 \ --prompt "The sound of a hammer hitting a wooden surface" \ --negative-prompt "Low quality" \ --seed 42 \ --guidance-scale 7.0 \ --audio-length 10.0 \ --num-inference-steps 100 \ --use-hsdp \ --hsdp-shard-size 2 \ --output stable_audio_output.wav显存紧张时还可组合--enable-cpu-offload(模型级)或--enable-layerwise-offload(逐层)来换取显存。仓库测试 tests/e2e/offline_inference/test_stable_audio_expansion.py 中亦验证了FP8 量化 + TeaCache与FP8 + CPU offload两种组合(quantization="fp8"、cache_backend="tea_cache"、enable_cpu_offload=True),说明该模型在 vLLM-Omni 中可叠加量化、缓存与 offload 能力。
在线服务:/v1/audio/generate 端点
启动服务端
配方给出的启动命令(与 docs/serving/audio_generate_api.md 快速开始一致):
vllm serve /path/to/stable-audio-open-1.0 \ --host 0.0.0.0 \ --port 8091 \ --gpu-memory-utilization 0.9 \ --trust-remote-code \ --enforce-eager \ --omni说明:--omni标志启用 vLLM-Omni 的多模态扩散服务模式,每个服务实例对应单一模型(启动时通过vllm serve <model> --omni指定)。--enforce-eager关闭 CUDA Graph 以降低启动显存开销,--gpu-memory-utilization 0.9允许模型使用 90% 显存。
生成请求(curl)
在另一个终端从仓库根目录发起请求:
curl http://localhost:8091/health curl -X POST http://localhost:8091/v1/audio/generate \ -H "Content-Type: application/json" \ -d '{ "input": "A gentle piano melody with soft room ambience", "audio_length": 10.0, "num_inference_steps": 50, "guidance_scale": 7.0, "negative_prompt": "Low quality, distorted, noisy", "seed": 42, "response_format": "wav" }' \ --output piano_10s.wav请求参数参考
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
input | string | 必填 | 描述待生成音频的文本提示词 |
model | string | 服务端模型 | 可选;若指定需与服务器模型一致 |
response_format | string | "wav" | 音频格式:wav、mp3、flac、pcm、opus |
speed | float | 1.0 | 播放速度(0.25 - 4.0) |
audio_length | float | null | 音频时长(秒);不传则用模型默认(stable-audio-open-1.0最大约 47 秒) |
audio_start | float | 0.0 | 音频起始时间(秒) |
negative_prompt | string | null | 负向提示词 |
guidance_scale | float | 模型默认 | CFG 强度,越高越贴合提示词 |
num_inference_steps | int | 模型默认 | 去噪步数,越高质量越好但更慢 |
seed | int | null | 复现用随机种子 |
响应为二进制音频数据,按response_format返回对应 Content-Type:wav→audio/wav、mp3→audio/mpeg、flac→audio/flac、pcm→audio/pcm、opus→audio/opus。服务端实现位于 vllm_omni/entrypoints/openai/serving_audio_generate.py,其中将audio_start + audio_length计算为audio_end_in_s后透传给管线。在线端到端测试见 tests/e2e/online_serving/test_stable_audio_online_expansion.py(使用 2 秒时长、4 步去噪的轻量用例校验/v1/audio/generate返回非空 WAV)。
Python 客户端示例
import httpx response = httpx.post( "http://localhost:8091/v1/audio/generate", json={ "input": "The sound of a cat purring", "audio_length": 10.0, }, timeout=300.0, ) with open("cat.wav", "wb") as f: f.write(response.content)参数调优指南
guidance_scale:3-5 更富创意/多样;7(默认)均衡;10+ 严格贴合提示词。num_inference_steps:50 步质量良好、速度快,适合快速预览;100 步质量很好,适合常规用途;150+ 质量最佳、速度最慢,适合最终成品。audio_length:stable-audio-open-1.0上限约 47 秒,省略时使用模型默认时长。negative_prompt:常用写法如"Low quality, distorted, noisy"、"Silence, static"、纯音效场景可用"Music"避免混入音乐。
常见错误响应
- 400 Bad Request:模型运行结束但未产生音频输出,报
"Audio generation model did not produce audio output."; - 404 Not Found:请求中
model与服务端不一致,报The model 'xxx' does not exist.; - 422 Unprocessable Entity:Pydantic 校验失败(如非法的
response_format或speed越界),detail中会列出"Input should be 'wav', 'pcm', 'flac', 'mp3' or 'opus'"等提示。
输出验证:采样率、时长与 WAV 合法性
配方对离线与在线两种输出都给出了soundfile校验脚本。离线输出验证:
ls -lh examples/offline_inference/text_to_audio/stable_audio_10s.wav python - <<'PY' import soundfile as sf path = "examples/offline_inference/text_to_audio/stable_audio_10s.wav" audio, sample_rate = sf.read(path) print("sample_rate:", sample_rate) print("shape:", audio.shape) print("duration:", len(audio) / sample_rate) PY在线输出验证(将路径换为piano_10s.wav即可)。验收标准:
- 离线命令写出合法 WAV 文件;
- 服务端在
http://localhost:8091/health正常响应; - 在线请求写出合法 WAV 文件;
- 生成音频采样率为44.1 kHz;
- 生成时长约为10 秒;
- 峰值采样显存控制在 RTX 4090 24GB 预算内——验证运行中离线与在线生成各自峰值约12.6 GiB。
硬件实测条目
1x NVIDIA RTX 4090 24GB(社区验证)
| 环境项 | 版本 |
|---|---|
| OS | Ubuntu 22.04.5 |
| Python | 3.12 |
| GPU | NVIDIA GeForce RTX 4090,24564 MiB VRAM |
| 驱动 / 运行时 | NVIDIA driver 595.80,与仓库构建匹配的 CUDA 运行时 |
| vLLM | 0.22.0 |
| vLLM-Omni | 源码检出(source checkout) |
| PyTorch | 2.11.0+cu130 |
命令即上文给出的离线与在线两条。验证结论:离线命令写出合法 WAV;服务健康检查与在线请求均正常;输出 44.1 kHz、约 10 秒;离线与在线生成峰值显存约 12.6 GiB。
1x AMD MI300X 192GB(社区验证)
| 环境项 | 版本 |
|---|---|
| OS | Linux 6.8.0-134-generic, x86_64 |
| 容器 | 由docker/Dockerfile.rocm构建的官方 ROCm 镜像 |
| Python | 3.12.13 |
| PyTorch | 2.11.0+gitd0c8b1f |
| 驱动 / 运行时 | AMD 6.19.14.31400000 / ROCm 7.2.53211 |
| GPU | AMD Instinct MI300X,gfx942:sramecc+:xnack-,191.69 GiB 可见 HBM |
| vLLM | 0.27.0+rocm723 |
| vLLM-Omni commit | 73e1368c7bb940efe1a025859c9d6c8eeeb2e3f0 |
命令(额外开启了--enable-diffusion-pipeline-profiler):
python3 examples/offline_inference/text_to_audio/text_to_audio.py \ --model stabilityai/stable-audio-open-1.0 \ --prompt "A gentle piano melody with soft room ambience" \ --negative-prompt "Low quality, distorted, noisy" \ --seed 42 \ --guidance-scale 7.0 \ --audio-length 10.0 \ --num-inference-steps 50 \ --cache-backend tea_cache \ --enable-diffusion-pipeline-profiler \ --output stable_audio_10s.wav验证结论与关键指标:
- 命令完成并写出合法的44.1 kHz 立体声 WAV,时长 10.00 秒;
- TeaCache 以
rel_l1_thresh=0.2运行; - 模型加载占用 2.7891 GiB、耗时 3.706 秒;
- 生成耗时 4.750 秒,对 10.00 秒输出而言实时因子(RTF)为 0.475(即生成比播放更快);
- 内部剖析器记录请求期间保留 15.65 GB、分配 9.68 GB;
- 全设备最高单秒内存采样为 19.61 GiB;
- 输出 RMS 为 0.0887,峰值绝对幅度为 0.5761;
- 整个进程(含启动与编译)耗时 384 秒。
注意事项与故障排查
配方明确记录的注意事项:
- torchaudio 版本匹配:在线服务若在导入
torchaudio时失败,需确保 torchaudio wheel 与已安装的 PyTorch/CUDA 构建匹配。验证环境使用torch==2.11.0+cu130与torchaudio==2.11.0+cu130; - 无害警告:验证中观察到的
NIXL is not available、GLOO_SOCKET_IFNAME、torchsde边界警告不会阻止生成成功; - 硬件边界:RTX 4090 条目在单张 24GB GPU 上验证,MI300X 条目覆盖单张 192GB GPU;更长的生成时长、更高推理步数与非 WAV 响应格式未在本配方中基准测试;
- 门控模型:必须先接受许可协议才能下载;
- 显存不足时:可降低
--gpu-memory-utilization(如 0.8)或缩短audio_length(见 docs/serving/audio_generate_api.md 的 Troubleshooting 部分); - 生成超时:减少
num_inference_steps、缩短audio_length,并用nvidia-smi检查显存。
延伸阅读
- 离线示例目录:examples/offline_inference/text_to_audio
- 离线脚本完整参数与用法:text_to_audio.py、README.md
- 在线 API 完整文档:docs/serving/audio_generate_api.md
- 管线实现:vllm_omni/diffusion/models/stable_audio/pipeline_stable_audio.py
- DiT 实现:vllm_omni/diffusion/models/stable_audio/stable_audio_transformer.py
- TeaCache 提取器:vllm_omni/diffusion/cache/teacache/extractors.py
- 端到端测试:tests/e2e/offline_inference/test_stable_audio_expansion.py、tests/e2e/online_serving/test_stable_audio_online_expansion.py
【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考