Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

text2token 的 C++ 实现 #1548

Open
endink opened this issue Nov 17, 2024 · 13 comments
Open

text2token 的 C++ 实现 #1548

endink opened this issue Nov 17, 2024 · 13 comments

Comments

@endink
Copy link
Contributor

endink commented Nov 17, 2024

程序内如果允许用户填入热词,C++ 没有直接可用的函数?

@csukuangfj
Copy link
Collaborator

@pkufool 帮忙回答。

@pkufool
Copy link
Contributor

pkufool commented Nov 17, 2024

@endink bpe 可以用 simple sentencepiece (参考热词里面的实现),拼音可以用 cppinyin,现在有一个没合并的 PR #967 。 我们正在训中英文的模型,并且可能会改建模单元,后面会有统一的 text2token C++ 实现。 你如果着急的话,可以按我上面说的自己实现。

@endink
Copy link
Contributor Author

endink commented Nov 18, 2024

谢谢,那 issue 暂时 open 吧, 其实就是如果热刺配置文件能传明文就不需要这个 API, 先自己写了,另外想问一下带 key words 参数的 CreateKeySpotterStream 里的 keyword 是 plain keyword 还是 encoded keyeord, 大概看了一眼源码是传 plain keyword, 代码里看起来会自己编码,我理解的对吗?因为代码还没搞完,也没测试,麻烦告知一下

@pkufool
Copy link
Contributor

pkufool commented Nov 18, 2024

KWS 传的应该是 encoded keyword, 因为涉及到pinyin的问题,还没加C++ 实现。 热词是可以传 plain text 的。

@endink
Copy link
Contributor Author

endink commented Nov 18, 2024

呃,了解了,谢谢解答,这里其实很复杂,不读代码很难弄清楚格式,建议有空时候完善一下文档,最好是能提供 C API 例子,因为现在 bin 里的例子是用更底层 CPP 实现,需要自己阅读 C API 源码去理解,总之,瑕不掩瑜, sherpa 自从有了 TTS 和 符号模型以后变成一个全能库了,赞一个

@pkufool
Copy link
Contributor

pkufool commented Nov 18, 2024

呃,了解了,谢谢解答,这里其实很复杂,不读代码很难弄清楚格式,建议有空时候完善一下文档,最好是能提供 C API 例子,因为现在 bin 里的例子是用更底层 CPP 实现,需要自己阅读 C API 源码去理解,总之,瑕不掩瑜, sherpa 自从有了 TTS 和 符号模型以后变成一个全能库了,赞一个

感谢你的建议,API 文档这块确实有些缺失。

@endink
Copy link
Contributor Author

endink commented Nov 18, 2024

@pkufool 你好,能在帮忙确认一下 SherpaOnnxCreateKeywordStreamWithKeywords keyword 是传 plain text (以 / 分割)吗?

我对比了 text2token-test.cc, 以中文为例:

这里我理解是明文传递?

TEST(TEXT2TOKEN, TEST_cjkchar) {
  std::ostringstream oss;
  oss << dir << "/text2token/tokens_cn.txt";

  std::string tokens = oss.str();

  if (!std::ifstream(tokens).good()) {
    SHERPA_ONNX_LOGE(
        "No test data found, skipping TEST_cjkchar()."
        "You can download the test data by: "
        "git clone https://github.com/pkufool/sherpa-test-data.git "
        "/tmp/sherpa-test-data");
    return;
  }

  auto sym_table = SymbolTable(tokens);

  std::string text =
      "世界人民大团结\n中国 V S 美国\n\n";  // Test blank lines also

  std::istringstream iss(text);

  std::vector<std::vector<int32_t>> ids;
  std::vector<float> scores;

   //这里是明文传递
  auto r = EncodeHotwords(iss, "cjkchar", sym_table, nullptr, &ids, &scores);

  std::vector<std::vector<int32_t>> expected_ids(
      {{379, 380, 72, 874, 93, 1251, 489}, {262, 147, 3423, 2476, 21, 147}});
  EXPECT_EQ(ids, expected_ids);

  EXPECT_EQ(scores.size(), 0);
}

keyword-spotter-transducer-impl.h 中的 CreateStream 函数:

 auto kws = std::regex_replace(keywords, std::regex("/"), "\n");
 std::istringstream is(kws);

 std::vector<std::vector<int32_t>> current_ids;
 std::vector<std::string> current_kws;
 std::vector<float> current_scores;
 std::vector<float> current_thresholds;

 if (!EncodeKeywords(is, sym_, &current_ids, &current_kws, &current_scores,
                     &current_thresholds)) {
   SHERPA_ONNX_LOGE("Encode keywords %s failed.", keywords.c_str());
   return nullptr;
 }

所以 SherpaOnnxCreateKeywordStreamWithKeywords 是明文传递吧

@endink
Copy link
Contributor Author

endink commented Nov 18, 2024

BTW, 我是用的 master 分支自己编译的

@pkufool
Copy link
Contributor

pkufool commented Nov 18, 2024

@endink 你看我上面的评论,这个是给热词用的, kws 还不能传正常文本,要传 encode 过的文本。

看名字,Hotwords 和 Keywords, 不是一样的。

@endink
Copy link
Contributor Author

endink commented Nov 18, 2024

看了你那个 PR, cppinyin 无法在 windows 下编译:

  • cppinyin.h(107,89): error C2001: newline in constant
  • cppinyin.cc(195,26): error C1075: '{': no matching token found

好难,等你们集成吧

@pkufool
Copy link
Contributor

pkufool commented Nov 18, 2024

看了你那个 PR, cppinyin 无法在 windows 下编译:

  • cppinyin.h(107,89): error C2001: newline in constant
  • cppinyin.cc(195,26): error C1075: '{': no matching token found

好难,等你们集成吧

估计是哪个地方搞错了,cppinyin 都有windows 下的 wheel,肯定是可以在 windows 下编译的。 可以,等我们集成吧。

@endink
Copy link
Contributor Author

endink commented Nov 19, 2024

@pkufool 看了你的 cmake , 基本上没有什么 options 需要调整, 我的 cmake 也很简单:

ExternalProject_Add(
    cppinyin
    GIT_REPOSITORY https://github.com/pkufool/cppinyin.git
    PREFIX         ${CMAKE_CURRENT_BINARY_DIR}
    INSTALL_DIR    ${CMAKE_CURRENT_BINARY_DIR}
    CMAKE_ARGS     -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
                   -DBUILD_STATIC_LIBS=ON
                   -DBUILD_SHARED_LIBS=OFF
                   -DCPPINYIN_BUILD_PYTHON=OFF
)

或许可以帮助复现问题

@endink
Copy link
Contributor Author

endink commented Dec 8, 2024

Is there any new good news here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants