Files
2026-07-13 13:33:03 +08:00

115 lines
5.4 KiB
C++

//
// tokenizer_demo.cpp
//
// Created by MNN on 2025/09/01.
// ZhaodeWang
//
#include "../src/tokenizer/tokenizer.hpp"
#include <chrono>
using namespace MNN::Transformer;
int main(int argc, const char* argv[]) {
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " tokenizer.txt [bench|test]" << std::endl;
return 0;
}
std::string tokenizer_path = argv[1];
std::string mode = (argc >= 3) ? argv[2] : "";
if (mode == "bench") {
// Benchmark mode: measure load time and encode/decode speed
int rounds = 5;
// 1. Load benchmark
double load_total = 0;
Tokenizer* tok = nullptr;
for (int i = 0; i < rounds; i++) {
auto t0 = std::chrono::high_resolution_clock::now();
tok = Tokenizer::createTokenizer(tokenizer_path);
auto t1 = std::chrono::high_resolution_clock::now();
load_total += std::chrono::duration<double, std::milli>(t1 - t0).count();
if (i < rounds - 1) delete tok;
}
printf("Load: avg %.2f ms (%d rounds)\n", load_total / rounds, rounds);
std::unique_ptr<Tokenizer> tokenizer(tok);
// 2. Encode benchmark (short strings)
std::vector<std::string> bench_strs = {
"介绍一下北京的首都",
"Hello World, this is a test of tokenizer performance.",
"The quick brown fox jumps over the lazy dog. 1234567890!@#$%",
"人工智能(Artificial Intelligence,简称AI)是计算机科学的一个分支,它企图了解智能的实质。",
};
int encode_rounds = 100;
double encode_total = 0;
int total_tokens = 0;
for (int r = 0; r < encode_rounds; r++) {
for (auto& s : bench_strs) {
auto t0 = std::chrono::high_resolution_clock::now();
auto ids = tokenizer->encode(s);
auto t1 = std::chrono::high_resolution_clock::now();
encode_total += std::chrono::duration<double, std::milli>(t1 - t0).count();
if (r == 0) total_tokens += ids.size();
}
}
printf("Encode(short): avg %.3f ms / call (%d strings x %d rounds, %d tokens/round)\n",
encode_total / (encode_rounds * bench_strs.size()), (int)bench_strs.size(), encode_rounds, total_tokens);
// 2b. Encode benchmark (long ~5K string)
std::string long_text;
{
std::string block = "在人工智能领域中,大型语言模型(Large Language Model, LLM)是一种基于深度学习的自然语言处理技术。"
"These models are trained on massive datasets containing billions of tokens from diverse sources including books, websites, and academic papers. "
"模型通过自注意力机制(Self-Attention)来捕捉文本中长距离的依赖关系,从而实现对语言的深层理解。"
"The transformer architecture, introduced in the seminal paper 'Attention Is All You Need', revolutionized the field of NLP. "
"在实际应用中,LLM被广泛用于对话系统、代码生成、文本摘要、翻译等多种任务。1234567890!@#$%^&*() ";
while (long_text.size() < 5000) long_text += block;
}
int long_rounds = 20;
double long_encode_total = 0;
int long_tokens = 0;
for (int r = 0; r < long_rounds; r++) {
auto t0 = std::chrono::high_resolution_clock::now();
auto ids = tokenizer->encode(long_text);
auto t1 = std::chrono::high_resolution_clock::now();
long_encode_total += std::chrono::duration<double, std::milli>(t1 - t0).count();
if (r == 0) long_tokens = (int)ids.size();
}
printf("Encode(long): avg %.3f ms / call (%d chars, %d tokens, %d rounds)\n",
long_encode_total / long_rounds, (int)long_text.size(), long_tokens, long_rounds);
// 3. Decode benchmark
auto sample_ids = tokenizer->encode(bench_strs[3]);
int decode_rounds = 1000;
double decode_total = 0;
for (int r = 0; r < decode_rounds; r++) {
for (auto id : sample_ids) {
auto t0 = std::chrono::high_resolution_clock::now();
auto s = tokenizer->decode(id);
auto t1 = std::chrono::high_resolution_clock::now();
decode_total += std::chrono::duration<double, std::milli>(t1 - t0).count();
}
}
printf("Decode: avg %.4f ms / token (%d tokens x %d rounds)\n",
decode_total / (decode_rounds * sample_ids.size()), (int)sample_ids.size(), decode_rounds);
return 0;
}
// Default mode: encode + decode correctness test
auto t0 = std::chrono::high_resolution_clock::now();
std::unique_ptr<Tokenizer> tokenizer(Tokenizer::createTokenizer(tokenizer_path));
auto t1 = std::chrono::high_resolution_clock::now();
printf("Load time: %.2f ms\n", std::chrono::duration<double, std::milli>(t1 - t0).count());
std::vector<std::string> test_strs = {"介绍一下北京的首都", "Hello World", "The quick brown fox"};
for (auto& s : test_strs) {
auto ids = tokenizer->encode(s);
std::string decoded;
for (auto id : ids) decoded += tokenizer->decode(id);
bool ok = (decoded == s);
printf("[%s] \"%s\" -> encode -> decode -> \"%s\"\n", ok ? "PASS" : "FAIL", s.c_str(), decoded.c_str());
}
return 0;
}