目录

tokenizers-moonbit

MoonBit 版 HuggingFace tokenizers。直接加载标准 tokenizer.json,在 wasmwasm-gcjsnative 后端运行同一套 encode/decode 实现,无 native 依赖。

项目定位:面向 LLM、边缘端和浏览器场景,在 Rust tokenizers 不便直接分发或 集成成本较高时,提供纯 MoonBit 的 tokenizer 运行时。

英文主页:README.md

目标

  • 跨后端一致。 同一份 MoonBit 源码编译到 wasm/wasm-gc/js/native,不依赖 FFI 或平台二进制。
  • 对齐 HuggingFace。 使用 Python tokenizers 生成期望结果,对真实模型做 token id 级对拍。
  • 直接复用 tokenizer.json 不需要转换格式,可复用 Python/Transformers 流水线中的 tokenizer 文件。
  • 可选 Hub 下载。 核心 loader 保持全后端/离线可用;hub 包可在 native/js 后端在线下载 tokenizer.json,并写入 HuggingFace 风格 cache。

支持范围

  • 模型: BPE、byte-level BPE(含 byte_fallback / fuse_unk / ignore_merges)、WordPiece、Unigram、WordLevel。
  • 流水线: Normalizer → Pre-tokenizer → Model → Post-processor → Decoder; 另支持 AddedVocabulary,用于识别文本中的 special/added token。
  • API: encodeencode_pairencode_batchdecode、truncation、 padding、token_to_idid_to_tokenget_vocab_size

在可选 fixture 存在时,对拍覆盖 39 个真实模型:gpt2、roberta、llama、 bert/bert-cased、distilbert、t5、albert、xlm-roberta、Qwen/DeepSeek/Phi/Mistral/ Falcon/StarCoder/GPT-NeoX/CLIP/GLM/Granite 家族、ModernBERT/GTE-ModernBERT、 SmolLM2,以及 BGE、E5、MiniLM、Jina、Nomic、MixedBread 等 embedding tokenizer。

正则兼容边界是显式的:主流 HuggingFace tokenizer 使用的常见 Split / Replace regex family 已用跨后端 deterministic scanner 实现;任意复杂正则,例如 look-around、backreference、完整通用 Unicode regex 语义,仍不在当前支持范围内。 迁移自定义 tokenizer 前请先查看 docs/components.md

组件状态见 docs/zh/components.md,路线图见 PROGRESS.md

文档

快速开始

Mooncakes 发布/依赖模块名:howtomakeaname/tokenizers-moonbit

moon new my-app && cd my-app
moon add howtomakeaname/tokenizers-moonbit

moon add 只会写入 moon.mod,还需要在使用方包的 moon.pkg 里声明子包导入:

import {
  "howtomakeaname/tokenizers-moonbit/tokenizer",
}

完整可运行程序(from_file/encode 在输入非法时会 raise,需用 try/catch 包裹;fn main 函数体不能直接调用会 raise 的函数):

fn main {
  try {
    // 从字符串加载(跨后端,无文件 IO):
    // let tok = @tokenizer.Tokenizer::from_str(json_text)
    // 或从文件加载(使用 moonbitlang/x/fs,全后端可用):
    let tok = @tokenizer.from_file("tokenizer.json")

    let enc = tok.encode("Hello world")
    println(enc.ids)
    println(enc.tokens)

    let pair = tok.encode_pair("question", "context")
    let text = tok.decode(enc.ids, skip_special_tokens=true)
    println(text)
  } catch {
    e => println("failed: \{e.message()}")
  }
}

运行:moon run cmd/main

native/js 可选:通过 hub 包在线下载。其入口是 async 函数,需要导入 moonbitlang/async(与本库声明的版本一致)、声明 supported_targets = "+js+native" 并使用 async fn main

async fn main {
  try {
    let tok = @hub.from_pretrained("bert-base-uncased")
    // 需要镜像时:
    let tok2 = @hub.from_pretrained(
      "bert-base-uncased",
      options=@hub.HubDownloadOptions::new(endpoint="https://hf-mirror.com"),
    )
    println(tok2.get_vocab_size())
  } catch {
    e => println("failed: \{e.message()}")
  }
}

encode(text, add_special_tokens=false) 会跳过 post-processor 模板;文本中已有的 special token 仍会被识别。完整细节见 docs/zh/usage.md

测试

export PATH="$HOME/.moon/bin:$PATH"
moon test
moon test --target native

完整模型对拍需要下载大文件 fixture:

python3 scripts/fetch_models.py
pip install tokenizers
python3 scripts/gen_parity.py
moon test --target native

fixture 缺失时,对拍测试自动跳过。

License

Apache-2.0。实现参考 HuggingFace tokenizers 的算法与文件格式。

关于

huggingface/tokenizers rewriten in moonbit language

4.1 MB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号