用 NVIDIA API Key 同时做画图和语音:一套从实测到落地的技术方案
用 NVIDIA API Key 同时做画图和语音:一套从实测到落地的技术方案
最近我在本地把一条很实用的链路跑通了:
- 用 NVIDIA API Key 生成图片
- 用 NVIDIA 官方 TTS 模型生成语音
- 把语音转换成 Feishu 可以直接播放的语音气泡
这篇文章不讲空泛概念,直接总结成一套可复用的技术方案。
先说结论:
同一个 NVIDIA API Key,确实可以同时用于画图和语音,但这两条链路的调用方式并不一样。
很多人第一次试的时候会踩一个坑:
- 画图用的是一套比较直接的 HTTP API
- 语音不是简单地去撞几个
/v1/audio/*endpoint 就能成功 - 真正跑通 TTS,要按 NVIDIA 官方示例走Riva / Speech NIM client的方式
如果这一点没搞清楚,很容易得出错误结论:
“图像接口能用,语音接口是不是根本不存在?”
其实不是。是入口不一样。
一、先搞清楚:NVIDIA 现在到底提供了什么能力
1. 图像生成:Stable Diffusion 3 Medium
在这套环境里,图像生成走的是 NVIDIA 提供的 SD3 Medium 接口。
本地脚本调用的是:
https://ai.api.nvidia.com/v1/genai/stabilityai/stable-diffusion-3-medium请求方式很直接:
Authorization: Bearer $NVIDIA_API_KEY- JSON body 里放
prompt、negative_prompt、steps
从工程实现上看,它更接近一个常规 REST 图像生成接口。
2. 语音生成:Magpie TTS / Riva TTS
语音这边不一样。
NVIDIA 官方现在有明确的 TTS 模型和文档体系,包括:
- Magpie TTS Multilingual
- Magpie TTS Zeroshot
- Magpie TTS Flow
其中最适合直接拿来做文本转语音的是:
Magpie TTS Multilingual
它支持多语言,官方文档里明确包含:
- English
- Spanish
- French
- German
- Mandarin
- Vietnamese
- Italian
而且支持多 voice、部分 voice 的情绪变体。
重点是:
它的官方调用示例,不是你以为的简单 REST/audio/speech,而是基于 Riva Python Client / gRPC 的方式。
这也是很多人第一次测不通的根源。
二、为什么很多人会误判“这把 key 不能做 TTS”
我一开始也先走了一个很自然的验证路径:
尝试访问类似下面这些 endpoint:
/v1/audio/generation/v1/audio/speech/v1/tts/v1/speech/synthesis/v1/riva/tts
结果几乎都是404。
如果到这里就停下,很容易得出一个错误结论:
“这把 NVIDIA API Key 只能画图,不能生成语音。”
但后来查了 NVIDIA 官方文档和 build 页面后就会发现:
不是没有 TTS,而是你走错了入口。
真正该走的是:
grpc.nvcf.nvidia.com:443- 带
function-id - 带
Bearer $NVIDIA_API_KEY - 用 Riva Python Client 去调用
talk.py
也就是说:
同样是 NVIDIA API Key,图像和 TTS 的接入方式属于两条不同的产品路径。
三、图像生成怎么接:最简单的可落地方案
我这边图像生成用的是一个本地脚本:
python3 skills/nvidia-nim/scripts/generate_image.py\--prompt"A scenic view of Shenzhen, China, modern skyline..."\--negative-prompt"blurry, low quality, distorted"\--steps30\--output./out.jpg它底层做的事其实不复杂:
- 从参数或环境变量读取
NVIDIA_API_KEY - 向 SD3 Medium 接口发 POST 请求
- 读取返回的 base64 图片
- 落盘到本地文件
核心实现可以概括成:
payload={'prompt':prompt,'negative_prompt':negative_prompt,'steps':steps,}curl-X POST \ https://ai.api.nvidia.com/v1/genai/stabilityai/stable-diffusion-3-medium \-H"Authorization: Bearer $NVIDIA_API_KEY"\-H"Accept: application/json"\-H"Content-Type: application/json"\-d'<payload>'一个容易踩的坑
虽然脚本暴露了这些参数:
cfg_scalewidthheight
但这个模型实际支持的关键字段主要是:
promptnegative_promptseedsteps
也就是说,Stable Diffusion 3 Medium 在这条 NVIDIA 接口上,并不是你传什么尺寸都能生效。
这个点如果不写清楚,后面排查“为什么尺寸没变”会很浪费时间。
四、TTS 怎么接:一定要按官方示例来
1. 安装官方 Python client
官方示例依赖:
pipinstall-Unvidia-riva-client以及官方仓库里的python-clients:
gitclone https://github.com/nvidia-riva/python-clients.git2. 官方关键调用方式
这次实测真正跑通的命令,本质上是:
python python-clients/scripts/tts/talk.py\--servergrpc.nvcf.nvidia.com:443 --use-ssl\--metadatafunction-id"877104f7-e885-42b9-8de8-f6e4c6303969"\--metadataauthorization"Bearer$NVIDIA_API_KEY"\--language-code zh-CN\--text"你好,这是一条测试语音。"\--voice"Magpie-Multilingual.ZH-CN.Siwei"\--outputaudio.wav这里最重要的是三个点:
A. server 不是普通 REST endpoint
而是:
grpc.nvcf.nvidia.com:443B. 必须带 function-id
这条 Magpie multilingual TTS 的 function-id,在我这次实测里用的是:
877104f7-e885-42b9-8de8-f6e4c6303969C. 需要按 Riva client 的参数格式传 metadata
也就是:
--metadatafunction-id"..."--metadataauthorization"Bearer$NVIDIA_API_KEY"3. 先 list voices,再决定用哪个 voice
这是一个很好的习惯。
先跑:
python python-clients/scripts/tts/talk.py\--servergrpc.nvcf.nvidia.com:443 --use-ssl\--metadatafunction-id"877104f7-e885-42b9-8de8-f6e4c6303969"\--metadataauthorization"Bearer$NVIDIA_API_KEY"\--list-voices我本地实际列出了很多 voice,其中中文可直接用的就包括:
Magpie-Multilingual.ZH-CN.SiweiMagpie-Multilingual.ZH-CN.HouZhen- 以及一些跨语言 voice 在
zh-CN下的映射项
这一步的意义很大:
不要先拍脑袋猜 voice name。先 list,再写死。
五、如果你要接 Feishu 语音气泡,还差一步格式转换
到这里,NVIDIA 已经能生成语音了,但它输出的是.wav。
问题是:
Feishu 想要“直接在聊天里点开播放”的效果,不是随便发个文件就行。
你要的是:
- 音频先转成合适格式(我这里用
.opus) - 再走 Feishu 的 audio message 接口
msg_type必须是audio
1. 先转 Opus
我这边用的是:
ffmpeg-iinput.wav-c:alibopus-b:a32k-ar24000-ac1output.opus为什么这么做?
因为这条链路对 Feishu 语音气泡比较稳,体积也小。
2. 再调用 Feishu audio API
这一步我本地封装成了一个 Python 脚本。它做的事情包括:
- 从 OpenClaw config 读取 Feishu app 凭据
- 获取 tenant access token
- 上传
opus文件 - 把
file_key作为msg_type=audio发给目标用户
这一步和 OpenClaw 自带tts的差别是:
OpenClaw 内置tts发出去更像普通音频文件;而这条链路能发成真正的 Feishu 语音气泡。
六、把它封装成一条可复用的命令,才是真正落地
如果只是“偶尔试一下”,你可能手动敲命令也无所谓。
但如果你想把它变成一个 daily-use capability,就不能停在 demo 阶段。
我最后做的,是把它封装成一个 shell shortcut:
bashskills/nvidia-feishu-voice-shortcut/scripts/send-nvidia-feishu-voice.sh\--text"这是一条测试语音"\--to<feishu_open_id>它内部串了 3 个步骤:
- 从
skills/nvidia-nim/.env读取NVIDIA_API_KEY - 用 NVIDIA 官方
talk.py生成.wav - 用
ffmpeg转.opus - 用 Feishu API 发送成语音气泡
这样以后你就不需要每次都记住:
- gRPC server 地址
- function-id
- 输出格式
- Feishu 上传流程
工程上真正省时间的,不是“知道原理”,而是:
把正确路径封装成一个稳定入口。
七、这套方案里最容易踩的坑
1. 把 TTS 当 REST API 去撞
这是最大坑。
NVIDIA 有 TTS,但不代表你随手猜一个/v1/audio/speech就能通。
2. 到处散落 API key
这一点我非常建议做清理。
最稳的做法是:
- 只保留一个 canonical secret store
- 例如:
skills/nvidia-nim/.env - 其他脚本统一从环境变量或这个
.env读 - 不要把真实 key 硬编码进脚本和 README
否则以后维护时会非常混乱,也有安全风险。
3. 图像和语音混用同一套调用思维
虽然它们都叫 NVIDIA API,但:
- 图像 = 直接 HTTP 图像生成
- 语音 = Speech NIM / Riva client / gRPC metadata
不要把一条链路的经验直接套到另一条链路上。
4. 忽略目标平台的媒体格式要求
即使语音已经生成成功,发到目标平台时也可能仍然不对。
例如 Feishu 这边,你需要关注:
- 编码格式
- duration
- 上传类型
- 消息类型是不是
audio
否则用户看到的可能只是一个附件,而不是可直接播放的语音气泡。
八、我对这套方案的判断
如果你问我,这套方案值不值得做,我的答案是:
值得,但前提是你把它做成 workflow,而不是停留在单次试验。
为什么?
因为单次 demo 的价值很有限,真正有价值的是下面这些能力:
- 一句话生成一张图
- 一句话生成一条语音
- 语音能直接投递到 Feishu / IM / workflow
- image 和 TTS 共用同一套 secret management
- 出错时你知道该查哪一层
这时候它才从“玩具”变成“能力”。
九、结语
这次实测之后,我对 NVIDIA 这套能力的感受是:
图像生成这条线,接入门槛很低;语音生成这条线,能力是有的,但必须尊重官方的调用范式。
所以最值得记住的不是某条命令,而是下面这句话:
同一个 NVIDIA API Key 可以同时做图像和语音,但图像走 REST,TTS 走 Riva / Speech NIM 官方路径,不能混着猜。
如果你把这条认知建立起来,再把它封装成自己的脚本和 shortcut,后面无论是画图、做语音,还是接到企业消息系统里,都会顺很多。
真正难的从来不是“API 能不能调通”,而是:
你能不能把一次成功,整理成一条可长期复用的工程路径。
