Liquid AIからLFM2-350M・LFM2-700M・LFM-1.2Bの3モデルがリリースされた。いずれも、英語・アラビア語・中国語・フランス語・ドイツ語・日本語・韓国語・スペイン語の8言語をサポートした生成言語モデルで、入出力幅(max position embeddings)が128000トークンもあるのに、パラメータ数がそれぞれ3.54億・7.42億・11.7億という超軽量が謳い文句だ。ただ、TransformersのLFM2サポートはv4.54.0以降に持ち越しになったので、それを待っているとQiita Tech Festaが終わっちゃう。とりあえず、日本語トークナイザのクセを見ておくことにしよう。
>>> from transformers import AutoTokenizer
>>> tkz=AutoTokenizer.from_pretrained("LiquidAI/LFM2-350M")
>>> print(tkz.convert_ids_to_tokens(tkz("国境の長いトンネルを抜けると雪国であった。","夜の底が白くなった。")["input_ids"]))
['<|startoftext|>', 'åĽ½', 'å¢ĥ', 'ãģ®', 'éķ·', 'ãģĦ', 'ãĥĪ', 'ãĥ³ãĥ', 'į', 'ãĥ«', 'ãĤĴ', 'æĬľ', 'ãģij', 'ãĤĭãģ¨', 'éĽª', 'åĽ½', 'ãģ§ãģĤãģ£ãģŁ', 'ãĢĤ', '<|startoftext|>', 'å¤ľ', 'ãģ®', 'åºķ', 'ãģĮ', 'çϽ', 'ãģıãģª', 'ãģ£ãģŁ', 'ãĢĤ']
うー、それは、2024年4月19日・4月25日・5月3日の記事と、ほぼ同じパターン…
>>> text="国境の長いトンネルを抜けると雪国であった。夜の底が白くなった。"
>>> x=tkz(text,return_offsets_mapping=True)
>>> for i,(s,e) in zip(x["input_ids"],x["offset_mapping"]):
... print(text[s:e],text[s:e].encode("utf-8"),ascii(tkz.convert_ids_to_tokens(i)))
...
b'' '<|startoftext|>'
国 b'\xe5\x9b\xbd' '\xe5\u013d\xbd'
境 b'\xe5\xa2\x83' '\xe5\xa2\u0125'
の b'\xe3\x81\xae' '\xe3\u0123\xae'
長 b'\xe9\x95\xb7' '\xe9\u0137\xb7'
い b'\xe3\x81\x84' '\xe3\u0123\u0126'
ト b'\xe3\x83\x88' '\xe3\u0125\u012a'
ンネ b'\xe3\x83\xb3\xe3\x83\x8d' '\xe3\u0125\xb3\xe3\u0125'
ネ b'\xe3\x83\x8d' '\u012f'
ル b'\xe3\x83\xab' '\xe3\u0125\xab'
を b'\xe3\x82\x92' '\xe3\u0124\u0134'
抜 b'\xe6\x8a\x9c' '\xe6\u012c\u013e'
け b'\xe3\x81\x91' '\xe3\u0123\u0133'
ると b'\xe3\x82\x8b\xe3\x81\xa8' '\xe3\u0124\u012d\xe3\u0123\xa8'
雪 b'\xe9\x9b\xaa' '\xe9\u013d\xaa'
国 b'\xe5\x9b\xbd' '\xe5\u013d\xbd'
であった b'\xe3\x81\xa7\xe3\x81\x82\xe3\x81\xa3\xe3\x81\x9f' '\xe3\u0123\xa7\xe3\u0123\u0124\xe3\u0123\xa3\xe3\u0123\u0141'
。 b'\xe3\x80\x82' '\xe3\u0122\u0124'
夜 b'\xe5\xa4\x9c' '\xe5\xa4\u013e'
の b'\xe3\x81\xae' '\xe3\u0123\xae'
底 b'\xe5\xba\x95' '\xe5\xba\u0137'
が b'\xe3\x81\x8c' '\xe3\u0123\u012e'
白 b'\xe7\x99\xbd' '\xe7\u013b\xbd'
くな b'\xe3\x81\x8f\xe3\x81\xaa' '\xe3\u0123\u0131\xe3\u0123\xaa'
った b'\xe3\x81\xa3\xe3\x81\x9f' '\xe3\u0123\xa3\xe3\u0123\u0141'
。 b'\xe3\x80\x82' '\xe3\u0122\u0124'
やはり、UTF-8のByte-Pair Encodingがナマで使われてる(ただし0x00~0x20・0x7f~0x9fはU+0100~U+0120・U+0121~U+0141へマッピング)上に、「トンネル」が3バイト・5バイト・1バイト・3バイトの4トークンにブッタ切られている。カタカナが文字の途中で千切れちゃうとなると、とてもじゃないけど、このままじゃ使えない。しかも、そこを直しても「抜」「け」「ると」とか「白」「くな」「った」とか、日本語トークナイザとしてはヒドイ状態だ。うーん、これで本当に日本語の生成、ちゃんとできるのかしら。