webassembly003 TTS BARK.CPP WordPiece

  • WordPiece是一种用于分词的子词划分算法,广泛应用于自然语言处理(NLP)任务中,代码中实现如下,使用贪心的方式进行编码,每次选择最长匹配的子串(i 到 j 之间的子串),并将对应的标记存储在 tokens 数组中
    // apply wordpiece
    for (const auto &word : words) {
        if (word.size() == 0)
            continue;

        std::string prefix = "";
        int i = 0;
        int n = word.size();

        loop:
            while (i < n) {
                if (t >= n_max_tokens - 1)
                    break;
                int j = n;
                while (j > i) {
                    auto it = token_map->find(prefix + word.substr(i, j - i));
                    if (it != token_map->end()) {
                        tokens[t++] = it->second;
                        i = j;
                        prefix = "##";
                        goto loop;
                    }
                    --j;
                }
                if (j == i) {
                    fprintf(stderr, "%s: unknown token '%s'\n", __func__, word.substr(i, 1).data());
                    prefix = "##";
                    ++i;
                }
            }
        }

转成可独立运行的代码如下:

#include <iostream>
#include <unordered_map>
#include <vector>

int main() {
    std::vector<std::string> words = {"用法解析"};
    const int n_max_tokens = 10;  // 最大标记数目,可以根据需求调整
    std::unordered_map<std::string, int> tokenmap = {
    {"用法",1},
    {"##解析",2},
    {"##析",3} };;  // 假设存在一个标记映射表
    
    std::unordered_map<std::string, int>  *token_map = &tokenmap;

    std::vector<int> tokens(n_max_tokens, 0);  // 存储标记的数组
    int t = 0;  // 当前标记的索引

    // 应用 WordPiece 分词算法
    for (const auto &word : words) {
        if (word.size() == 0)
            continue;

        std::string prefix = "";
        int i = 0;
        int n = word.size();

    loop:// loop是一个标签(label),在这段 C++ 代码中,它被用作跳转语句 goto 的目标
        while (i < n) {
            if (t >= n_max_tokens - 1)
                break;

            int j = n;
            while (j > i) {
                auto it = token_map->find(prefix + word.substr(i, j - i));
                if (it != token_map->end()) {
                    tokens[t++] = it->second;
                    i = j;
                    prefix = "##";
                    goto loop;
                }
                --j;
            }

            // 处理未知的单个字符,可以根据需求进行适当的处理
            if (j == i) {
                fprintf(stderr, "%s: unknown token '%s'\n", __func__, word.substr(i, 1).c_str());
                prefix = "##";
                ++i;
            }
        }
    }

    // 输出处理后的标记,输出应为:Tokens: 1 2 
    std::cout << "Tokens: ";
    for (int i = 0; i < t; ++i) {
        std::cout << tokens[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

CG

在这里插入图片描述

  • 12
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值