Thinker 离线翻译示例 ==================== 功能说明 -------- 本示例在 ARCS AP Core 上运行 Thinker Transformer Encoder/Decoder,将固定的英文 句子离线翻译为中文。示例复用一块 PSRAM 模型缓冲区依次运行 Encoder 和 Decoder,并从外部 Flash 直接查询紧凑词表,不依赖网络或 Host 侧 Python 环境。 硬件连接 -------- 无需外部连接,Thinker、Luna、PSRAM 和外部 NOR Flash 均为开发板资源。示例支持 ``arcs_evb`` 和 ``arcs_mini``,两种板型都搭载带 16 MiB PSRAM 的 LS2684。 示例步骤 -------- 1. 从词表资源查找英文单词 ID,生成不超过 32 个词元的 Encoder 输入。 2. 从 Flash 加载 ``arcs_encoder.bin`` 到 PSRAM,运行 Encoder 并保存 ``int8 [1, en_len, 256]`` memory tensor。 3. 释放 Encoder 后复用模型缓冲区,加载 ``arcs_decoder.bin``。 4. Decoder 使用贪婪搜索逐个生成中文词元,遇到 EOS 或达到 32 个词元时结束。 5. Decoder 每步同时传入 ``int8 [1, 8, de_len, de_len]`` 因果掩码,防止注意力读取未来词元。 6. 将中文词元拼接后输出到日志。 资源布局 -------- 应用和三个运行资源需要分别烧录: .. list-table:: :header-rows: 1 * - 资源 - Flash 偏移 - 默认 XIP 地址 - 大小 * - ``lnn_thinker_translation.bin`` - ``0x000000`` - ``0x30000000`` - 不超过 1 MiB * - ``arcs_encoder.bin`` - ``0x100000`` - ``0x30100000`` - ``0x6CC060`` * - ``arcs_decoder.bin`` - ``0x800000`` - ``0x30800000`` - ``0x650160`` * - ``translation_vocab.bin`` - ``0xE80000`` - ``0x30E80000`` - ``0x3BE61`` 编译 ---- .. include:: /sample_build.rst 烧录 ---- 先烧录应用,再烧录 Encoder、Decoder 和词表资源: .. code-block:: bash cskburn -C arcs -s /dev/ttyACM0 -b 3000000 \ 0x0 build/lnn_thinker_translation.bin \ 0x100000 build/arcs_encoder.bin \ 0x800000 build/arcs_decoder.bin \ 0xE80000 build/translation_vocab.bin 构建时 CMake 会把三个 ``resources/`` 文件复制到构建目录。烧录完成后设备自动 复位;日志串口波特率为 921600。 预期输出 -------- .. code-block:: text [I][thinker_translation] translation input: May the Force be with you. [I][translation_vocab] vocabulary ready: source=15080 target=4362 size=245345 [I][offline_translation] encoder forward cost: ... ms [I][offline_translation] decoder forward total cost: ... ms steps=9 [I][thinker_translation] translation result: 愿力量与你同在。 模型使用与 ARCS Thinker 3.0.10 LayerNorm 实现一致的 Q10 归一化尺度。 Encoder 和 Decoder 在打包前已通过 Linger ONNXRunner/Thinker 逐层一致性验证, 默认句子的 x86 Thinker 与实板都应输出上述翻译。 配置说明 -------- 待翻译英文句子由 ``src/main.c`` 中的 ``s_translation_sentence`` 设置。板端预处理与 训练工程保持一致,会先转为小写、删除最后一个字符再按空白分词,因此句子必须以 标点结尾,且加上 BOS/EOS 后不能超过 32 个词元。 模型地址、大小和运行内存池由以下配置控制: .. code-block:: kconfig CONFIG_THINKER_TRANSLATION_ENCODER_MODEL_ADDR=0x30100000 CONFIG_THINKER_TRANSLATION_ENCODER_MODEL_SIZE=0x6CC060 CONFIG_THINKER_TRANSLATION_DECODER_MODEL_ADDR=0x30800000 CONFIG_THINKER_TRANSLATION_DECODER_MODEL_SIZE=0x650160 CONFIG_THINKER_TRANSLATION_VOCAB_ADDR=0x30E80000 CONFIG_THINKER_TRANSLATION_VOCAB_SIZE=0x3BE61 CONFIG_THINKER_TRANSLATION_PSRAM_POOL_SIZE=0x20000 CONFIG_THINKER_TRANSLATION_SHARE_POOL_SIZE=0x60000 核心 API -------- .. list-table:: :header-rows: 1 * - API - 说明 * - ``tGetMemoryPlan()`` - 获取当前 Encoder 或 Decoder 的运行内存计划。 * - ``tModelInit()`` - 从 PSRAM 中的 Thinker 模型资源创建模型。 * - ``tCreateExecutor()`` - 创建当前模型执行器。 * - ``tSetInput()`` - 设置词元 ID、Encoder memory tensor 或 Decoder 因果掩码,并写入实际输入维度。 * - ``tUpdateShape()`` - 设置全部输入后,根据输入 Tensor 推导动态 Shape。 * - ``tForward()`` - 执行一次 Encoder 或 Decoder 推理。 * - ``tGetOutput()`` - 读取 Encoder memory tensor 或 Decoder 概率张量。 词表重新生成 ------------ 如果训练侧 ``vocab.json`` 发生变化,使用脚本重新生成紧凑词表: .. code-block:: bash labs/lnn/thinker_translation/scripts/generate_vocab.py \ /path/to/vocab.json \ labs/lnn/thinker_translation/resources/translation_vocab.bin 生成后必须同步更新 ``CONFIG_THINKER_TRANSLATION_VOCAB_SIZE``,并确保模型的英文、 中文词表大小仍分别为 15080 和 4362。 注意事项 -------- 1. **资源必须配套**:两个 Thinker 模型和词表来自同一次训练/转换结果,不能单独替换。 2. **Flash 容量**:默认布局占用约 14.8 MiB,只适用于至少 16 MiB NOR Flash 的板卡。 3. **PSRAM 复用**:Encoder 和 Decoder 不能同时驻留;修改代码时要保留先释放再加载的顺序。 4. **量化输出**:Decoder 输出为 ``int8 [1, de_len, 4362]``,每步直接对量化分数取最大值。 5. **词表校验**:板端启动时会检查词表头、尺寸、词表项数量和 payload CRC32。