🤖

【LLM】TokenizerとEmbedding

に公開

tokenizer

tokenizerの役割は、「トークン化」

日本語ではサブワード化がよく利用されていて、作成にするにはいくつかパターンがある。

  • MeCabを用いて単語に分割し、WordPieceでサブワード化
  • SentencePieceでサブワード化

HFで推論時にtokenizer利用するときはHF用のtokenizerに変換する。

関連するライブラリに関して

SentencePiece

https://github.com/google/sentencepiece

→ 二つのアルゴリズムのタイプをサポート

  • BPE(バイト ペア エンコーディング)
  • ユニグラム言語モデル(デフォルトのタイプはこっち)

単語間に明示的なスペースが存在しない日本語や中国語にサブワードを適用しようとすると、事前にMeCab等で分割する必要が生まれるが、生文から直接分割を学習することで、事前の分割処理を行う必要がなくなる。

低頻度の固有名詞→分割されていく。
高頻度の言葉→1トークンになる。

(en) Hello world. → [Hello] [World] [.] (A space between Hello and World)
(ja) こんにちは世界。 → [こんにちは] [世界] [。] (No space between こんにちは and 世界)

llama2のtokenizer

まずHuggingFace(HF)版のllama2を参考にtokenizerに関連するファイルを確認してみる。

tokenizer.model →トークナイザー モデル
tokenizer.json → トークナイザーの語彙設定
tokenizer_config.json → tokenizerのためのコンフィグファイル(Special Tokenの設定など)

tokenizer.model

tokenizer.modelからtokenizerをロードすることができる。

llama2のtokenizer.modelからロード
tokenizer = LlamaTokenizer.from_pretrained("tokenizer.model")

tokenizer_config.json

スペシャルトークンの設定等が含まれている。

tokenizer_config.jsonの中身
{
  "add_bos_token": true,
  "add_eos_token": false,
  ...(省略)
  "bos_token": "<s>",
  "clean_up_tokenization_spaces": false,
  "eos_token": "</s>",
  "legacy": true,
  "model_max_length": 1000000000000000019884624838656,
  "pad_token": null,
  "sp_model_kwargs": {},
  "spaces_between_special_tokens": false,
  "tokenizer_class": "LlamaTokenizer",
  "unk_token": "<unk>",
  "use_default_system_prompt": false
}

embedding

ベクトルに変換する。

embeddingの用途

  • LLM内でのembedding
  • RAG利用時でベクトルストア構築時での利用

Sentence Transformersというオープンソースライブラリがある。

LangChainを利用する時の注意点


llmで利用するtokenizerとLangchain(RAG)で利用するtokenizerは図の通り同一である必要はない。

参考

https://qiita.com/taku910/items/7e52f1e58d0ea6e7859c

Discussion