文本分词器模块
文本分词器模块负责把字符串转换成模型可用的 token ID 序列。
这层只做分词、编码与反向解码,不负责模型推理。典型流程是先把文本编码成 MLMultiArray 或 onnxruntime.tensor,再把编码结果传给对应的 CoreML 或 ONNX Runtime 推理器。
当前这套模块的目标是“端侧推理够用”:
WordPiece兼容度最高,适合BERT、CN-CLIP一类模型BPE和SentencePiece采用轻量兼容策略,适合多数端侧编码场景- 不把复杂分词器训练、采样或完整上游生态行为搬到运行时里
该模块在 20260319 以后版本方可使用
创建分词器
coreml.new_text_tokenizer(opts)
文本分词器对象, 错误信息 = coreml.new_text_tokenizer({
type = 分词器类型,
vocab_path = 词表路径,
merges_path = merges 文件路径,
model_path = SentencePiece 模型路径,
pattern = 正则表达式,
context_length = 上下文长度,
do_lower_case = 是否转小写,
vocab_limit = 词表上限,
clean_text = 是否先清洗文本,
add_bos = 是否添加起始 token,
add_eos = 是否添加结束 token,
bos_token = 起始 token 文本,
eos_token = 结束 token 文本,
pad_token = 填充 token 文本,
unk_token = 未知 token 文本,
})
type 取值
wordpiece/bert/cn_clipbpe/gpt2_bpe/clip_bpesentencepiece/spmregex/patternbyte/byteswhitespace/spacecharacter/char
默认 wordpiece。
如果 coreml.new_text_tokenizer(...) 的第一个参数不是 table,会直接按 wordpiece 快捷构造处理,也就是等价于 coreml.new_wordpiece_tokenizer(vocab_path) 这类用法。
常用参数
-
vocab_path
文本型,词表文件路径。 -
merges_path
文本型,BPE系分词器使用的 merges 文件路径。 -
model_path
文本型,SentencePiece兼容模式可使用的.model文件路径。 -
pattern
文本型,Regex分词器使用的正则表达式。 -
context_length
整数型,可选参数,输出 token 序列长度。 -
do_lower_case
布尔型,可选参数,是否先转小写。 -
vocab_limit
整数型,可选参数,仅WordPiece常用,用于限制词表上限。 -
clean_text
布尔型,可选参数,是否在分词前先做基础文本清洗。 -
add_bos / add_eos
布尔型,可选参数,是否在编码结果前后附加起始 / 结束 token。 -
bos_token / eos_token / pad_token / unk_token
文本型,可选参数,对应特殊 token 在词表中的文本。
不是所有分词器类型都支持上面所有字段。当前实现的必填项与默认值如下:
wordpiece支持直接传vocab_path字符串,或传 table;要求vocab_path存在;默认context_length = 52、do_lower_case = true、vocab_limit = 21128,并要求词表里存在[PAD]、[UNK]、[CLS]、[SEP]bpe只接受 table;要求vocab_path和merges_path;默认context_length = 77、do_lower_case = false、clean_text = false、add_bos = false、add_eos = falsesentencepiece只接受 table;要求vocab_path或model_path至少一个;默认context_length = 77、do_lower_case = false、clean_text = true、bos_token = "<s>"、eos_token = "</s>"、pad_token = "<pad>"、unk_token = "<unk>"regex只接受 table;要求vocab_path和pattern;默认context_length = 77、do_lower_case = false、clean_text = truewhitespace/character/byte只接受 table;要求vocab_path;默认context_length = 77、do_lower_case = false、clean_text = true
选择建议:
- 已知模型使用
vocab.txt + WordPiece,就选wordpiece - 已知模型使用
vocab.json + merges.txt,就选bpe - 已知模型使用
.vocab或.model,就选sentencepiece - 只有简单规则切词需求时,再考虑
regex、whitespace、character、byte
返回值
-
文本分词器对象
对象型,创建失败返回nil。 -
错误信息
文本型,成功时为nil,失败时返回错误信息。
说明
- 分词器对象适合创建一次后复用,不建议每次编码都重新构造
- 创建阶段主要决定三件事:分词算法、词表来源、固定输出长度
- 如果模型效果明显不对,优先检查分词器类型、词表文件、special token 配置和
context_length是否与训练时一致 WordPiece是当前最完整、最稳的一类BPE和SentencePiece以端侧编码兼容为目标,不承诺复刻所有上游实现的全部细节
快捷构造器
以下快捷函数本质上都是对 coreml.new_text_tokenizer(...) 的转发,适合在你已经确定分词器类型时直接使用。
coreml.new_wordpiece_tokenizer(opts)
- 等价于
coreml.new_text_tokenizer({ type = "wordpiece", ... }) - 适合
BERT、CN-CLIP等WordPiece风格文本模型 - 也支持直接传词表路径字符串:
coreml.new_wordpiece_tokenizer(vocab_path)
coreml.new_bpe_tokenizer(opts)
- 等价于
coreml.new_text_tokenizer({ type = "bpe", ... }) - 同时覆盖
gpt2_bpe、clip_bpe一类vocab.json + merges.txt模型
coreml.new_sentencepiece_tokenizer(opts)
- 等价于
coreml.new_text_tokenizer({ type = "sentencepiece", ... }) - 使用面向端侧推理的轻量兼容实现
- 支持
.vocab和.model
coreml.new_regex_tokenizer(opts)
- 等价于
coreml.new_text_tokenizer({ type = "regex", ... }) - 适合基于规则切词和简单词表映射的场景
coreml.new_byte_tokenizer(opts)
- 等价于
coreml.new_text_tokenizer({ type = "byte", ... }) - 会先把文本转成
UTF-8字节流,再按字节查词表
coreml.new_whitespace_tokenizer(opts)
- 等价于
coreml.new_text_tokenizer({ type = "whitespace", ... }) - 适合空格切词、词表直查的轻量文本模型
coreml.new_character_tokenizer(opts)
- 等价于
coreml.new_text_tokenizer({ type = "character", ... }) - 适合字符级文本模型
类型判断
coreml.is_text_tokenizer(value)
是否文本分词器 = coreml.is_text_tokenizer(需要判断的值)
用于判断一个值是否为 coreml_text_tokenizer_object。
对象方法
:encode(text[, opts])
编码结果, 错误信息 = 文本分词器对象:encode(文本)
或
编码结果, 错误信息 = 文本分词器对象:encode(文本, {
output = "table" 或 "MLMultiArray" 或 "ort_tensor",
data_type = 数据类型,
pair_text = 配对文本,
max_length = 最大长度,
padding = 填充策略,
truncation = 截断策略,
return_attention_mask = 是否返回 attention mask,
return_token_type_ids = 是否返回 token type ids,
return_special_tokens_mask = 是否返回 special tokens mask,
})
把单个文本编码成 token 序列。
:encode_batch(texts[, opts])
编码结果, 错误信息 = 文本分词器对象:encode_batch(文本数组)
或
编码结果, 错误信息 = 文本分词器对象:encode_batch(文本数组, {
output = "table" 或 "MLMultiArray" 或 "ort_tensor",
data_type = 数据类型,
pair_text = 配对文本或配对文本数组,
max_length = 最大长度,
padding = 填充策略,
truncation = 截断策略,
return_attention_mask = 是否返回 attention mask,
return_token_type_ids = 是否返回 token type ids,
return_special_tokens_mask = 是否返回 special tokens mask,
})
一次编码多个文本,返回 batch 形式的 token 序列。
:decode(ids)
文本, 错误信息 = 文本分词器对象:decode(ids)
把单条 token id 序列反向解码成文本。
ids可以是 Lua 数组、MLMultiArray,或者 ORT tensor 之类的 tensor-like userdataids也可以是任何实现了shape()与to_table()的 tensor-like userdata- 如果传入的是 batch 数据,会报错并提示改用
decode_batch()
:decode_batch(batch_ids)
文本数组, 错误信息 = 文本分词器对象:decode_batch(batch_ids)
把 batch token id 序列反向解码成文本数组。
batch_ids可以是嵌套 Lua 数组、MLMultiArray,或者 ORT tensor 之类的 tensor-like userdatabatch_ids也可以是任何实现了shape()与to_table()的 tensor-like userdata
:vocab_size()
词表大小 = 文本分词器对象:vocab_size()
返回当前分词器可用词表大小。
:context_length()
上下文长度 = 文本分词器对象:context_length()
返回当前分词器的固定输出长度,也就是单次编码会补齐或截断到的长度。
编码与返回说明
output默认是"MLMultiArray",适合直接喂给 CoreML 模型output = "table"适合调试、查看 token id,或兼容旧脚本output = "ort_tensor"适合直接喂给 ONNX Runtime 文本模型output = "ort_tensor"前必须先执行require("onnxruntime"),这样 ORT 桥接接口才会被注入output = "ort_tensor"依赖 ONNX Runtime,因此仅支持 iOS 13+- 为兼容旧脚本,字段
multi_array_output仍会被读取;但新代码建议统一使用output
data_type 规则
output = "MLMultiArray"时,data_type可选"int32"、"float32"、"float16"、"double";"float64"可作为"double"的别名output = "MLMultiArray"时,默认data_type = "int32"output = "ort_tensor"时,data_type可选"float16"、"float32"、"uint8"、"int8"、"int32"、"int64"、"double"、"bool"output = "ort_tensor"时,默认data_type = "int64"
padding / truncation
padding可以是布尔值,也可以是字符串true会映射到"max_length"false会映射到"do_not_pad"
truncation可以是布尔值,也可以是字符串true会映射到"longest_first"false会映射到"do_not_truncate"
pair_text
encode()里可以传单个pair_textencode_batch()里可以传单个pair_text,也可以传与 batch 大小一致的字符串数组
结构化返回
当以下任一字段为 true 时,encode() / encode_batch() 会返回结构化结果表,而不只是裸 token 序列:
return_attention_maskreturn_token_type_idsreturn_special_tokens_mask
结构化结果常见字段:
input_idslengthattention_masktoken_type_idsspecial_tokens_mask
对 batch 编码来说:
output = "table"时,保留每条样本自己的长度output = "MLMultiArray"/"ort_tensor"时,会把 batch 补齐成规则矩阵后再返回
示例
local tokenizer = assert(coreml.new_text_tokenizer({
type = "wordpiece",
vocab_path = XXT_HOME_PATH.."/models/demo/vocab.txt",
context_length = 52,
}))
local ids = assert(tokenizer:encode("星星", {
output = "MLMultiArray",
data_type = "int32",
}))
local structured = assert(tokenizer:encode("星星", {
output = "table",
return_attention_mask = true,
return_token_type_ids = true,
}))
local ort = require("onnxruntime")
local input_ids = assert(tokenizer:encode("星星", {
output = "ort_tensor",
data_type = "int64",
}))
local batch = assert(tokenizer:encode_batch({
"星星",
"月亮",
}, {
output = "ort_tensor",
}))
print(tokenizer:decode(structured.input_ids))
print(tokenizer:vocab_size())
print(tokenizer:context_length())