Перейти к основному содержимому

Модуль текстового токенизатора

Модуль текстового токенизатора преобразует строки в последовательности 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_clip
  • bpe / gpt2_bpe / clip_bpe
  • sentencepiece / spm
  • regex / pattern
  • byte / bytes
  • whitespace / space
  • character / char

По умолчанию — wordpiece.

Если первый параметр coreml.new_text_tokenizer(...) не является table, он обрабатывается как сокращённая конструкция wordpiece, то есть эквивалентен вызову вроде coreml.new_wordpiece_tokenizer(vocab_path).

Распространённые параметры

  • vocab_path
    Текстовое значение, путь к файлу словаря.
  • merges_path
    Текстовое значение, путь к файлу merges для токенизаторов семейства BPE.
  • model_path
    Текстовое значение, путь к файлу .model в совместимом режиме SentencePiece.
  • 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 = false
  • sentencepiece: принимает только 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 = true
  • whitespace / 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", ... })
  • Подходит для текстовых моделей в стиле WordPiece, включая BERT и CN-CLIP
  • Также принимает строковый путь к словарю: 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,
})

Кодирует несколько текстов и возвращает последовательности token в форме batch.

:decode(ids)

текст, сообщение_об_ошибке = объект_токенизатора:decode(ids)

Декодирует одну последовательность token id обратно в текст.

  • ids может быть массивом Lua, MLMultiArray или tensor-like userdata, например ORT tensor
  • ids также может быть любой tensor-like userdata с реализациями shape() и to_table()
  • При передаче batch-данных будет ошибка с предложением использовать decode_batch()

:decode_batch(batch_ids)

массив_текстов, сообщение_об_ошибке = объект_токенизатора:decode_batch(batch_ids)

Декодирует batch последовательностей token id обратно в массив текстов.

  • batch_ids может быть вложенным массивом Lua, MLMultiArray или tensor-like userdata, например ORT tensor
  • batch_ids также может быть любой tensor-like userdata с реализациями shape() и to_table()

: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_text
  • В encode_batch() можно передать один pair_text или массив строк размера batch

Структурированный результат

Если любое из следующих полей имеет значение true, encode() / encode_batch() возвращает таблицу структурированного результата, а не только чистую последовательность token:

  • return_attention_mask
  • return_token_type_ids
  • return_special_tokens_mask

Распространённые поля структурированного результата:

  • input_ids
  • length
  • attention_mask
  • token_type_ids
  • special_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())