机器翻译组件
简介
ACOMP Translation 是 ARCS SDK 的机器翻译组件,提供基于文本输入的机器翻译功能。该组件支持中英文双向翻译(英译中、中译英),采用 Encoder-Decoder 架构,支持多组编码器和解码器模型,翻译结果通过事件回调返回。
主要特性
双向翻译:支持英文到中文(EN→CN)和中文到英文(CN→EN)双向翻译
Encoder-Decoder 架构:采用多组编码器(A-F)和解码器模型,支持复杂的翻译任务
结果类型配置:支持设置翻译结果的返回类型
事件回调机制:支持翻译结果返回和翻译状态通知
快捷 API:提供
acomp_translation_do_prepare()/acomp_translation_do_cleanup()快捷接口,简化资源管理混合存储:模型资源支持 Flash 和 eMMC 混合存储
跨核通信:基于 IPC 机制实现文本和翻译结果的跨核传输
配置选项
基本配置
配置项 |
说明 |
默认值 |
|---|---|---|
|
启用 ACOMP 组件 |
n |
|
启用 ACOMP 组件的翻译组件 |
n |
资源配置
翻译组件包含英译中(ENCN)和中译英(CNEN)两套模型,每套包含 6 个编码器(A-F)、1 个解码器和对应的词嵌入模型,所有模型资源存储在 eMMC 中。
英译中 (ENCN) 模型资源(仅列出部分编码器,C-F 配置项结构与 A/B 相同):
配置项 |
说明 |
默认值 |
|---|---|---|
|
编码器 A eMMC 地址 |
0x0 |
|
编码器 A 大小(字节) |
3306480 |
|
编码器 B eMMC 地址 |
0x328000 |
|
编码器 B 大小(字节) |
3286864 |
… |
编码器 C-F 配置(各含 EMMC_ADDR 和 SIZE) |
… |
|
解码器 eMMC 地址 |
0x131a000 |
|
解码器大小(字节) |
4429216 |
|
解码器词嵌入 eMMC 地址 |
0x1754000 |
|
解码器词嵌入大小(字节) |
1936384 |
|
编码器词嵌入 eMMC 地址 |
0x192d000 |
|
编码器词嵌入大小(字节) |
1936384 |
中译英 (CNEN) 模型资源:配置结构与 ENCN 相同,配置项前缀为 CONFIG_ACOMP_TRANS_RES_CNEN_*。
此外还需要 Flash 中的翻译词典(trandb)和传统词典(dict_trad)资源,通过 resmgr 获取。
快速开始
方式一:使用快捷 API(推荐)
快捷 API 封装了完整的初始化、资源加载和启动流程:
#include "translation/acomp_translation.h"
void trans_event_handler(uint32_t event, void *event_data,
uint32_t event_data_len, void *priv)
{
if (event & TRANS_CB_EVENT_RESULT) {
// 翻译结果
printf("Translation result: %.*s\n", event_data_len, (char *)event_data);
} else if (event & TRANS_CB_EVENT_STATUS) {
uint32_t status = *(uint32_t *)event_data;
printf("Translation status: %u\n", status);
}
}
void translation_quick_start(void)
{
// 初始化 ACOMP 框架
acomp_init();
// 一键准备并启动翻译组件
int ret = acomp_translation_do_prepare(trans_event_handler, NULL);
if (ret != 0) {
printf("Translation prepare failed: %d\n", ret);
return;
}
// 提交翻译文本
const char *text = "Hello, world";
acomp_translation_translate(text, strlen(text));
// 翻译结果将通过 TRANS_CB_EVENT_RESULT 回调返回
// 清理
acomp_translation_do_cleanup();
}
方式二:使用标准 API
1. 启用组件
在项目的 prj.conf 文件中添加:
# 启用 ACOMP 组件
CONFIG_ACOMP=y
# 启用 ACOMP 组件的翻译组件
CONFIG_ACOMP_TRANSLATION=y
2. 初始化翻译组件
#include "acomp.h"
#include "translation/acomp_translation.h"
int main(int argc, char **argv)
{
// 初始化 ACOMP 框架
acomp_init();
// 初始化翻译组件
int ret = acomp_translation_init();
if (ret != ACOMP_ERR_OK) {
printf("Translation init failed: %d\n", ret);
return -1;
}
return 0;
}
3. 注册事件回调
#include "translation/acomp_translation.h"
void trans_event_handler(uint32_t event, void *event_data,
uint32_t event_data_len, void *priv)
{
if (event & TRANS_CB_EVENT_RESULT) {
printf("Translation result: %.*s\n", event_data_len, (char *)event_data);
} else if (event & TRANS_CB_EVENT_STATUS) {
uint32_t status = *(uint32_t *)event_data;
printf("Translation status: %u\n", status);
}
}
// 注册回调
int ret = acomp_translation_add_callback(
TRANS_CB_EVENT_RESULT | TRANS_CB_EVENT_STATUS,
trans_event_handler,
NULL
);
4. 准备资源并启动
void start_translation_service(acomp_ipc_prepare_t *prepare)
{
int ret;
// 1. 就绪组件(传入资源配置)
ret = acomp_translation_prepare(prepare);
if (ret != ACOMP_ERR_OK) {
printf("Translation prepare failed: %d\n", ret);
return;
}
// 2. 启动翻译
ret = acomp_translation_start();
if (ret != ACOMP_ERR_OK) {
printf("Translation start failed: %d\n", ret);
return;
}
printf("Translation service started\n");
}
5. 执行翻译
void do_translate(const char *text)
{
int ret = acomp_translation_translate(text, strlen(text));
if (ret != ACOMP_ERR_OK) {
printf("Translate failed: %d\n", ret);
}
// 翻译结果通过 TRANS_CB_EVENT_RESULT 回调返回
}
API 参考
生命周期管理
acomp_translation_init
int acomp_translation_init(void);
功能:初始化翻译组件
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_NO_MEM:内存不足ACOMP_ERR_INVALID_STATE:组件已初始化ACOMP_ERR_NOT_FOUND:设备未找到
acomp_translation_prepare
int acomp_translation_prepare(acomp_ipc_prepare_t *prepare);
功能:就绪翻译组件,将资源配置发送给 AP 端
参数:
prepare:资源配置数据结构指针
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_ARG:参数错误
acomp_translation_start
int acomp_translation_start(void);
功能:启动翻译组件
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_STATE:无效状态
acomp_translation_stop
int acomp_translation_stop(void);
功能:停止翻译组件
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_STATE:无效状态
acomp_translation_cleanup
int acomp_translation_cleanup(void);
功能:清理翻译组件资源,注销 IPC 回调并释放回调链表
返回值:
ACOMP_ERR_OK:成功
快捷 API
acomp_translation_do_prepare
int acomp_translation_do_prepare(trans_event_cb_t event_cb, void *cb_priv);
功能:一键准备并启动翻译组件
说明:封装了 init、回调注册、资源加载(eMMC + Flash resmgr)和 start 的完整流程。资源地址来自 Kconfig 配置。不会清理其他算法组件,调用方需自行协调。
参数:
event_cb:事件回调函数(首次调用时注册,可为 NULL)cb_priv:回调函数的私有数据指针
返回值:
0:成功负值:错误
acomp_translation_do_cleanup
int acomp_translation_do_cleanup(void);
功能:一键停止并清理翻译组件
返回值:
0:成功
翻译控制
acomp_translation_translate
int acomp_translation_translate(const char *text, uint32_t len);
功能:提交文本进行翻译
参数:
text:待翻译的文本字符串len:文本长度(字节)
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_ARG:text 为 NULL 或 len 为 0ACOMP_ERR_NO_MEM:内存不足
acomp_translation_set_res_type
int acomp_translation_set_res_type(int type);
功能:设置翻译结果类型
参数:
type:结果类型值
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_STATE:无效状态
事件回调
acomp_translation_add_callback
int acomp_translation_add_callback(uint32_t events, trans_event_cb_t cb, void *priv);
功能:添加事件回调函数
参数:
events:事件位掩码,可同时注册多个事件TRANS_CB_EVENT_RESULT:翻译结果返回TRANS_CB_EVENT_STATUS:翻译状态通知
cb:回调函数指针priv:回调函数的私有数据指针
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_STATE:无效状态
acomp_translation_remove_callback
int acomp_translation_remove_callback(trans_event_cb_t cb);
功能:移除回调函数
参数:
cb:待移除的回调函数
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_STATE:无效状态
使用示例
完整示例
#include "acomp.h"
#include "translation/acomp_translation.h"
#include "lisa_log.h"
#define TAG "trans_demo"
void trans_event_handler(uint32_t event, void *event_data,
uint32_t event_data_len, void *priv)
{
if (event & TRANS_CB_EVENT_RESULT) {
LISA_LOGI(TAG, "Translation result: %.*s", event_data_len, (char *)event_data);
} else if (event & TRANS_CB_EVENT_STATUS) {
uint32_t status = *(uint32_t *)event_data;
LISA_LOGI(TAG, "Translation status: %u", status);
}
}
void translation_demo(void)
{
int ret;
// 1. 初始化 ACOMP 框架
acomp_init();
// 2. 一键准备并启动翻译组件
ret = acomp_translation_do_prepare(trans_event_handler, NULL);
if (ret != 0) {
LISA_LOGE(TAG, "Translation prepare failed: %d", ret);
return;
}
LISA_LOGI(TAG, "Translation started");
// 3. 英译中
const char *en_text = "Hello, how are you?";
ret = acomp_translation_translate(en_text, strlen(en_text));
if (ret != ACOMP_ERR_OK) {
LISA_LOGE(TAG, "Translate failed: %d", ret);
}
// 4. 等待翻译结果(通过回调返回)
vTaskDelay(pdMS_TO_TICKS(3000));
// 5. 中译英
const char *cn_text = "你好世界";
ret = acomp_translation_translate(cn_text, strlen(cn_text));
if (ret != ACOMP_ERR_OK) {
LISA_LOGE(TAG, "Translate failed: %d", ret);
}
// 6. 等待翻译结果
vTaskDelay(pdMS_TO_TICKS(3000));
// 7. 清理
acomp_translation_do_cleanup();
LISA_LOGI(TAG, "Translation cleaned up");
}
注意事项
初始化顺序:必须先调用
acomp_init()初始化 ACOMP 框架快捷 API 推荐:推荐使用
acomp_translation_do_prepare()快捷 API,自动处理 20 项模型资源的加载模型资源:翻译组件需要大量模型资源(ENCN 和 CNEN 各 9 项 + 词典 2 项),确保 eMMC 和 Flash 中的资源正确烧录
算法协调:快捷 API 不会清理其他算法组件(如 CV、XTTS),调用方需自行管理算法生命周期
异步结果:翻译结果通过
TRANS_CB_EVENT_RESULT事件回调异步返回事件回调:回调函数在组件内部线程中执行,应避免长时间阻塞操作
内存管理:组件使用动态内存分配,确保系统有足够的堆内存
跨核通信:文本和翻译结果基于 IPC 机制传输,注意跨核数据传输的延迟
常见问题
Q: 翻译组件初始化失败怎么办?
A: 检查以下几点:
确保 ACOMP 框架已正确初始化
检查系统是否有足够的堆内存
确认 AP 核固件已正确烧录
Q: 翻译没有返回结果?
A: 检查:
确认已正确注册
TRANS_CB_EVENT_RESULT事件回调确认翻译文本非空
检查模型资源是否正确加载(eMMC 和 Flash 中的所有资源)
Q: 翻译结果不准确怎么办?
A: 建议:
检查输入文本是否符合模型支持的语言
尝试调整翻译结果类型(
acomp_translation_set_res_type())确保所有模型资源版本一致
Q: 翻译速度很慢怎么办?
A: 建议:
减少每次翻译的文本长度
确保 AP 核没有被其他算法任务占用
检查 eMMC 读取速度是否正常
依赖项
ACOMP 框架:算法组件框架resmgr:Flash 资源管理器(用于加载翻译词典)lisa_log:日志系统lisa_mem:内存管理FreeRTOS:实时操作系统翻译算法库:Encoder-Decoder 翻译算法引擎