IoT-For-Beginners 多语言智能计时器:在 Raspberry Pi 上用 Azure Translator REST API 实现语音翻译
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
本篇指南基于 IoT-For-Beginners 开源课程项目的消费者项目第 4 课,讲解如何在 Raspberry Pi 上用 Python 调用 Azure Translator REST API 为语音交互应用添加双向文本翻译能力。读完后,你将掌握"用户语言 ↔ 服务器语言"的双语架构设计、Translator REST API 的完整调用方式(URL、请求头、参数、批量请求体与响应解析),以及一个可直接运行的智能计时器端到端实现。
为什么需要翻译:双语言架构
在多语言智能设备的典型架构中,应用的核心逻辑(语言理解 LUIS、应答文本的生成)通常只基于一种"服务器语言"训练和构建。为了让用户用自己的母语与设备对话,需要在语音识别之后、语言理解之前插入一次"用户语言 → 服务器语言"的翻译;在设备应答时,再插入一次"服务器语言 → 用户语言"的翻译。
下图展示了 smart timer 的完整多语言数据流:用户语音经麦克风采集后先做语音识别(STT)得到用户语言文本,Translator 将其翻译为服务器语言文本,经 Azure IoT Hub 与 Azure Functions 交给 LUIS 理解并生成应答文本,Functions 再经 IoT Hub 把应答发回设备,翻译回用户语言后合成语音(TTS)播放:
这一架构的关键前提是:Speech 服务的 REST API 并不支持在识别时直接附带翻译(内置翻译能力仅存在于 Speech SDK),因此课程选择用独立的 Translator 服务在设备端完成文本翻译,而智能计时器的其余部分保持不变。相关课程背景见 课程 README,设备端完整实现见 code/pi 目录。
第一步:定义用户语言与服务器语言两个变量
智能计时器需要同时持有两种语言:
language:用户实际说出的语言(用于语音识别与语音合成);server_language:训练 LUIS 模型所用的语言(也是应答文本的原始生成语言)。
在app.py顶部做如下更新:
language = '<user language>' server_language = '<server language>'将<user language>替换为你将说出的语言的区域名(locale),例如法语是fr-FR;将<server language>替换为训练 LUIS 所用的语言区域名。
提示(来自原文档):如果你不会说第二种语言,可以先用在线翻译工具把"set a 2 minute and 27 second timer"这类句子从服务器语言翻译成目标语言,并播放其发音,对着设备说出来即可。原文档中的示例即法语场景,区域名为
fr-FR。
第二步:配置 Translator API 密钥
Speech 服务需要先向 token issuer API 换取 access token,而Translator 服务不需要——它直接接受 API key。因此在speech_api_key下方新增:
translator_api_key = '<key>'<key>替换为你的 Translator 资源的 API key。该资源通过 Azure CLI 创建(见 课程 README):
az cognitiveservices account create --name smart-timer-translator \ --resource-group smart-timer \ --kind TextTranslation \ --sku F0 \ --yes \ --location <location> az cognitiveservices account keys list --name smart-timer-translator \ --resource-group smart-timer \ --output table第三步:实现translate_text函数
在say函数上方定义translate_text函数。from与to语言作为参数传入,因为应用需要在两个方向上使用它——识别语音时从用户语言转到服务器语言,提供语音应答时从服务器语言转回用户语言:
def translate_text(text, from_language, to_language):构造 URL 与请求头
url = f'https://api.cognitive.microsofttranslator.com/translate?api-version=3.0' headers = { 'Ocp-Apim-Subscription-Key': translator_api_key, 'Ocp-Apim-Subscription-Region': location, 'Content-type': 'application/json' }注意两点实现细节:
- URL 与 location 的关系:Speech 服务的 REST 端点是按区域划分的(如
https://{location}.stt.speech.microsoft.com/...),而 Translator 的端点api.cognitive.microsofttranslator.com是全球统一的,区域信息通过Ocp-Apim-Subscription-Region请求头传递; - 鉴权方式:API key 通过
Ocp-Apim-Subscription-Key请求头直接传递,无需像 Speech 服务那样调用issuetoken接口获取 Bearer token。
构造参数与请求体
params = { 'from': from_language, 'to': to_language } body = [{ 'text' : text }]params指定翻译方向:把from语言的文本翻译成to语言;body是要翻译的文本。请求体是一个数组——因为同一次调用中可以批量翻译多个文本块。
发起请求并解析响应
response = requests.post(url, headers=headers, params=params, json=body)响应是一个 JSON 数组,其中第一项包含translations数组,对应请求体中每个文本项的翻译结果:
[ { "translations": [ { "text": "Set a 2 minute 27 second timer.", "to": "en" } ] } ]从数组第一项的第一条翻译中取出text属性并返回:
return response.json()[0]['translations'][0]['text']第四步:在主循环中翻译用户语音
更新while True主循环,将convert_speech_to_text识别出的文本从用户语言翻译到服务器语言后再发给 IoT Hub:
if len(text) > 0: print('Original:', text) text = translate_text(text, language, server_language) print('Translated:', text) message = Message(json.dumps({ 'speech': text })) device_client.send_message(message)这段代码同时把原文与译文打印到控制台,便于调试识别与翻译环节。
第五步:在say函数中翻译应答文本
更新say函数,把要朗读的文本从服务器语言翻译回用户语言,再交给 TTS:
def say(text): print('Original:', text) text = translate_text(text, server_language, language) print('Translated:', text) speech = get_speech(text) play_speech(speech)get_speech会用language(用户语言)对应的 voice 构造 SSML 并调用 TTS 端点,因此翻译后的文本正好与合成语音的语言匹配。
运行与预期输出
确保 Functions 应用正在运行,然后用用户语言(自己说或用翻译工具播放音频)请求一个计时器:
pi@raspberrypi:~/smart-timer $ python3 app.py Connecting Connected Using voice fr-FR-DeniseNeural Original: Définir une minuterie de 2 minutes et 27 secondes. Translated: Set a timer of 2 minutes and 27 seconds. Original: 2 minute 27 second timer started. Translated: 2 minute 27 seconde minute a commencé. Original: Times up on your 2 minute 27 second timer. Translated: Chronométrant votre minuterie de 2 minutes 27 secondes.提示(来自原文档):由于不同语言表达同一意思的方式不同,你得到的识别/翻译文本可能与你给 LUIS 的示例略有差异。遇到这种情况,应给 LUIS 增加更多示例,然后重新训练并重新发布模型。
源码级解析:完整设备端实现
课程给出的完整代码位于 code/pi/smart-timer/app.py,其中与翻译直接相关的调用链如下:
- translate_text:即上文逐步构建的函数,一次
requests.post完成翻译,返回response.json()[0]['translations'][0]['text']; - convert_speech_to_text:STT 端点按区域划分(
{location}.stt.speech.microsoft.com),通过get_access_token()获取 Bearer token,并把language作为查询参数传入——这就是"识别的是用户语言"的落点; - say:翻译后调用
get_speech/play_speech,SSML 中的xml:lang与 voice 均基于用户语言; - 主循环:按住按钮采集音频 → STT → 翻译 → 以
{"speech": text}的 JSON 消息发送到 IoT Hub。
从源码结构看,翻译被放置在设备端有两个原因:一来识别出的文本必须先进入服务器语言才能被 LUIS 理解,这一步在消息离开设备前完成;二来应答文本在进入 TTS 前完成回译,保证合成语音的语言与用户一致。
同一翻译能力的三种落点:设备端、云端与 SDK
课程在同一个 code 目录下给出了三套实现,可以对照理解翻译能力的不同放置位置:
- 树莓派(本篇):设备端直接用 REST API 调用 Translator,密钥写在设备代码中,适合资源充足、能自由出网的单板机;
- WIO Terminal:资源受限的嵌入式设备改为调用 Azure Functions 中的 translate-text 函数 作为代理。C++ 侧的 TextTranslator 类 将
text、from_language、to_language序列化为 JSON POST 到TRANSLATE_FUNCTION_URL,由 Functions 侧读取环境变量TRANSLATOR_KEY与TRANSLATOR_LOCATION完成真正的 API 调用,再返回翻译文本——密钥因此不落在设备上; - 虚拟设备:识别环节改用 Speech SDK 的
TranslationRecognizer(SpeechTranslationConfig中设置speech_recognition_language与target_languages),SDK 在识别的同时直接返回目标语言文本,识别方向不再需要 REST 翻译;但 TTS 方向仍保留与树莓派版一致的 RESTtranslate_text实现,见 virtual-iot-device/smart-timer/app.py。Functions 侧的环境变量配置可在 local.settings.json 中对照查看(TRANSLATOR_KEY、TRANSLATOR_LOCATION)。
三种方案对应同一条架构主线:识别与合成用 Speech 服务,翻译用 Translator 服务;差异只在于翻译调用放在设备端 REST、云端代理还是 SDK 内置能力。
后续方向与清理
完成本课后的进阶任务是用两台设备(其中一台可以是虚拟设备)搭建"通用翻译机":一台配置为一种语言,另一台配置为另一种语言,各自把语音转为文本经 IoT Hub 与 Functions 发给对方,翻译后播放——完整要求见 assignment.md。
本课是消费者项目的最后一课。课程 README 提醒:完成课程与作业后,应按 clean-up 指南 清理你创建的 cloud 资源(Speech、Translator、IoT Hub、Functions 等),以免产生不必要的费用。
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考