tk3.biz
ブログ一覧に戻る Back to Blog

128K の文書の奥まで、ちゃんと読めているのか 128K の文書の奥まで、ちゃんと読めているのか

AIローカルLLMQwenllama.cpp測定

はじめに

128K の回で、こう書いたままでした。

128K は動く。……ここまで測ったのは速度だけです。

動くことと、読めていることは別です。 13 万トークンの文書を渡して、その奥に書いてあることを本当に拾えるのか。 これを確かめないまま「128K 対応」と言うのは片手落ちでした。

測る準備は前回で整っています。 文書を一度読ませれば、2 回目以降の質問は 10 秒ほどで返ってきます。 以前なら 1 問ごとに 20 分の読み込みが必要でしたが、今は 1 回の読み込みで何十問も聞けます。

測り方

いわゆる needle-in-a-haystack(干し草の中の針)です。

  • 干し草: このシリーズの作業記録を連結した文書(約 13 万トークン)
  • 針: 「検証メモ: 備品番号 XA-4752 の保管棚は 2740 番です。」という文を 20 個、 深さ 2.5% から 97.5% まで 5% 刻みで差し込む
  • 質問: 「備品番号 XA-4752 の保管棚は何番ですか」を 1 つずつ聞く
  • 引っかけ: 文書に無い番号を 4 つ聞き、「記載なし」と答えられるかを見る

引っかけを入れたのは、正解率だけでは「分からないときにでっち上げる」癖が見えないからです。 存在しない番号に、それらしい数字を答えてしまうなら、それも読めていないのと同じです。

比較する条件は 3 つです。

条件狙い
16K・f16基準。短ければ全部答えられるか
128K・f16本題。長くしたら落ちるか
128K・K を q8_0128K で 6〜11% 速かった設定で、正答率が落ちないか

16K の基準が大事です。128K で間違えたとき、長さのせいなのか、 そもそも答えられない問題なのかを切り分けられます。

測る前に潰した落とし穴

thinking の回では、採点スクリプトのバグを 2 回踏みました。 今回は測る前に、思いつく落とし穴を潰しました。

落とし穴対策
本文全体に正規表現をかけ、途中の数字に反応する「答え:」の行だけを見る
\b が日本語で効かない数字は (?<!\d)2740(?!\d) で囲む
答えの数字が、元の文書に偶然含まれている実行時に文書を検索し、含まれない数字だけを使う
スクリプト自身や結果ファイルが文書に紛れ込む文書から除外する(紛れ込むと答えが文書に書いてあることになる)
計測中にスリープするスクリプト自身がスリープを抑止する

3 つ目と 4 つ目は、干し草を「このリポジトリの文書」から作っているので起きうる問題です。 結果ファイルには前回の答えが全部書いてあります。それを干し草に混ぜたら、測っているのは記憶ではなく検索です。

採点器は、本番の前に 12 通りの文字列で確かめました。

OK  True  : 答え: 4821番
OK  True  : 答え: **4821** 番の棚です
OK  True  : 途中の説明 1482 | 答え: 4821番
OK  False : 答え: 1482番
OK  False : 答え: 48210番
OK  False : 4821番です(答えの行なし)
OK  True  : 答え: 記載なし
OK  False : 答え: 不明(3321番かもしれません)
……
採点器の検証: 12 件すべて期待どおり

それでも 1 つ踏んだ: 答えの前に打ち切られていた

16K の試走で、1 問だけ「答えの行が空」で不正解になりました。

採点器は検証済みです。では何が起きたのか。 最初のスクリプトは答えの行しか残していなかったので、分かりません。 不正解のときは本文全体を残すように直して、もう一度流しました。

本文: 備品番号 AF-6519 に関する記述は、2つ目の記事「……」内の
「測り方をしくじった話」のセクションにあります。 記載

モデルは答えの前に説明を書き始め、max_tokens 64 の上限で打ち切られていました。 「答え:」の行に届く前に、私が止めていたわけです。

これでは、取り出しに失敗したのか、書く前に切られたのかを区別できません。 上限を 256 に上げると、16K は 20 問すべて正解になりました。

採点器を検証しても、採点器に渡す前の段階に穴がありました。 助けになったのは、不正解の本文を実際に読んだことです。

結果

20か所の深さごとの正誤。16Kは20/20。128Kのf16とKをq8_0にした条件はどちらも22.5%の位置の1問だけ不正解で19/20、その1問はHC-8189を聞いたのにHC-2388の値を答えていた。HC-2388をMK-2388に改名すると20/20になった

条件針(20 問)記載なし(4 問)初回の読み込み1 問あたり
16K・f1620/204/456 秒3 秒
128K・f1619/204/419.5 分11 秒
128K・K を q8_019/204/419.6 分12 秒

深さ 2.5% でも 97.5% でも拾えています。 文書の真ん中あたりで取りこぼす、 といった傾向は見えませんでした。

文書に無い番号 4 つは、**全条件で「記載なし」**と答えています。でっち上げはゼロでした。

K の量子化は、正答率に影響しませんでした。間違えた 1 問の答えまで、f16 と完全に同じです。

唯一の誤りは、深さのせいではなかった

128K で間違えた 1 問は、2 条件とも同じでした。

22.5% の位置  HC-8189 → 正解 2539   モデルの答え: 8953
92.5% の位置  HC-2388 → 正解 8953

答えた 8953 は、文書の別の場所にある、別の番号の値です。 しかもその番号は、同じ 「HC-」で始まっています。

深いところの情報を見失ったのではなく、似た番号を取り違えて、後ろ(質問に近い)ほうを答えたように見えます。 16K では同じ組み合わせで正解しているので、長くなると起きやすくなるのでしょう。

ここまでは推測です。確かめるために、HC-2388 だけを MK-2388 に改名して、同じ 128K をもう一度流しました。 文書、位置、値は一切変えていません。

条件針HC-8189 の答え
128K・f1619/208953(HC-2388 の値)
128K・HC-2388 を MK-2388 に改名20/202539(正解)

改名しただけで正解に変わりました。 取り違えで確定です。

ただし、言えるのは「この 1 組については」までです。 先頭 2 文字が同じ組は、20 個の中にこの 1 組しかありませんでした。

1 文字目だけが同じ組なら、ほかにもあります(X が XA / XY / XX の 3 つ、W が WE / WP / WA の 3 つ、H が HC-8189 / HP-1922 / HC-2388 の 3 つ)。 こちらは取り違えていません(HP-1922 も正解)。取り違えたのは 2 文字まで一致した組だけでした。 「似た番号は必ず取り違える」「後ろのほうを答えやすい」と一般化できるほどの件数はありません。

どう使えばいいか

128K の文書でも、奥に書いてあることは拾えます。 少なくとも、この種の「番号を引く」質問では。

気をつけるのは長さよりも、似た名前のものが文書の中に複数あるときです。 コードで言えば、getUserById と getUserByIdOrNull のような関数が離れた場所にあるケースが近いでしょう。 長い文書で似た名前のものについて聞くなら、答えを鵜呑みにせず、該当箇所を確かめたほうが安全です。

K の量子化は、正答率を落とさずに 128K で 6〜11% 速くなる設定だと分かりました。 ただ、128K の回で書いたとおり、 普段使っている 2 万トークン前後では速くならないので、既定の設定は変えていません。

この結論が言えないこと

  • 問題の種類が 1 つだけです。「番号を引く」は取り出しの中でも易しい部類で、 複数の箇所を突き合わせる質問や、要約のような課題は測っていません
  • 針は 1 条件 20 個です。1 問の誤りで 5% 動く粒度なので、条件の細かい差は言えません
  • 干し草はこのシリーズの作業記録です。内容の性質が違う文書では結果が変わるかもしれません

まとめ

  • 128K でも 20 問中 19 問。深さによる取りこぼしは見えなかった
  • 文書に無いことは**全部「記載なし」**と答えた。でっち上げなし
  • 唯一の誤りは、先頭 2 文字が同じ別の番号との取り違え。片方を改名すると消えた
  • K の量子化は正答率に影響なし
  • 採点器を検証しても、max_tokens の打ち切りという穴が残っていた。不正解の本文を読んで見つけた

「128K で読めるか」の答えは、読める。ただし似たものは取り違えることがある、でした。

関連記事 Related Posts

使っていない画像機能を外したら、メモリは1GiB減り、速度は変わらなかった 使っていない画像機能を外したら、メモリは1GiB減り、速度は変わらなかった

ローカルLLMのサーバが、テキストしか使わないのに画像用のmmprojを毎回読み込んでいました。外すと速くなるかを、前回まとめたチェックリストに沿って測りました。1回目は計測中のずれが大きく速度について何も言えず、裏で別のAIセッションが動いていたと分かったので、止めて測り直しました。メモリは1GiB減り、速度は3%未満の差で変わりませんでした。既定は外すことにしました。 ローカルLLMのサーバが、テキストしか使わないのに画像用のmmprojを毎回読み込んでいました。外すと速くなるかを、前回まとめたチェックリストに沿って測りました。1回目は計測中のずれが大きく速度について何も言えず、裏で別のAIセッションが動いていたと分かったので、止めて測り直しました。メモリは1GiB減り、速度は3%未満の差で変わりませんでした。既定は外すことにしました。

128K の文書は、読ませ直さずに使い回せるのか 128K の文書は、読ませ直さずに使い回せるのか

ローカルLLMに128Kトークンの文書を読ませると20分以上かかります。2回目以降を速くできるか、プロンプトキャッシュを6通りの使い方で測りました。質問を変えるだけなら数秒で済みますが、ディスクに保存して再起動すると全部読み直しになります。理由はモデルのハイブリッド構成にありました。以前の記事の誤りも見つかりました。 ローカルLLMに128Kトークンの文書を読ませると20分以上かかります。2回目以降を速くできるか、プロンプトキャッシュを6通りの使い方で測りました。質問を変えるだけなら数秒で済みますが、ディスクに保存して再起動すると全部読み直しになります。理由はモデルのハイブリッド構成にありました。以前の記事の誤りも見つかりました。

コンテキストを 128K まで伸ばしたら、壁はメモリではなく待ち時間だった コンテキストを 128K まで伸ばしたら、壁はメモリではなく待ち時間だった

ローカルLLMのコンテキストを32Kから128Kまで伸ばして測りました。予想していたメモリ不足は起きず、理由はモデルの構造にありました。代わりに見えた壁はプロンプトの取り込み時間で、128Kを読ませるだけで21〜24分かかります。途中で自分の自動起動に計測を汚された話も含みます。 ローカルLLMのコンテキストを32Kから128Kまで伸ばして測りました。予想していたメモリ不足は起きず、理由はモデルの構造にありました。代わりに見えた壁はプロンプトの取り込み時間で、128Kを読ませるだけで21〜24分かかります。途中で自分の自動起動に計測を汚された話も含みます。