クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

量子化でモデルの何が変わるか

このレッスンのあとで: 数を小さくすると何が失われるかを説明できる。

60分のレッスンコマンド7件AI コーディングエージェントのラボ:opencode でコードを説明・修正し、その結果を確かめる

数を小さくすると、モデルも小さくなる

モデルを量子化するとは、中の数をより少ないビットで保存することです。モデルが使うメモリは減りますが、代わりにどの数も丸められます。

大きなモデルを小さなパソコンに詰め込むのは、この丸めのおかげです。結果を信じる前に、何を払ったのかを知っておく必要があります。

このレッスンのゴール

メモ

数を小さくすると何が失われるかを説明できる。

キーワード

ことばいみ
量子化数を、決まった少ない段に丸めること
段数が丸められる先の値の一つ
スケール表の中で、絶対値がいちばん大きい値
誤差元の数と、丸めて戻した数との差
外れ値他よりずっと大きな値

学生が入力するセルは、このプレビューでは空白です。

ビットが少ないと、段も少ない

8 ビットなら、数は 255 の段のどれかに置けます。4 ビットでは 15 段、2 ビットでは 3 段しかありません。どの数も、いちばん近い段に動かされます。

段を決めるには、各値をスケール(絶対値の最大)で割り、いちばん上の段を掛けて、丸めます。数を戻すには、手順を逆にたどります。

八つの数を四つの精度で

ビット段の数残る整数最大の誤差
8255127 -59 10 71 -124 44 -7 900.0031
4157 -3 1 4 -7 2 0 50.0586
373 -1 0 2 -3 1 0 20.12
231 0 0 1 -1 0 0 10.42

学生が入力するセルは、このプレビューでは空白です。

丸めがいちばん痛むところ

先に痛むのは、小さな数です。4 ビットでは -0.05 が 0 になり、失われました。2 ビットでは、八つのうち四つが 0 になります。

外れ値が一つあると、全員が痛みます。値の一つが 9.0 なら、スケールが 9.0 になり、段の間が広がって、小さな数はみな 0 に丸まります。

よくある間違い

注意

「ビットを減らすと、全体が少しぼやけるだけだ」と考えがちです。実際は均等ではありません。小さな数は消え、外れ値が一つで表全体を壊すことがあります。量子化した表は、信じる前に、必ず誤差を測ります。

モデル用の補助を書く(1)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// 応答に含まれるトークン数。なければ null。' 'function count(data, name) {' '  return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

モデル用の補助を書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function ask(messages, sample, max) {' '  try {' '    const res = await fetch(base + \"/v1/chat/completions\", {' '      method: \"POST\",' '      headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' '      body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' '      signal: AbortSignal.timeout(30000),' '    });' '    if (res.ok === false) throw new Error(\"status \" + res.status);' '    const d = await res.json();' '    return { text: d.choices[0].message.content, inTokens: count(d, \"prompt_tokens\"), outTokens: count(d, \"completion_tokens\"), recorded: false };' '  } catch (error) {' '    console.log(\"記録済みサンプル: モデルが答えませんでした (\" + error.message + \")。\");' '    return { text: sample, inTokens: null, outTokens: null, recorded: true };' '  }' '}' 'module.exports = { ask };' >> model.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

量子化するスクリプトを書く(1)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const values = [0.9, -0.42, 0.07, 0.5, -0.88, 0.31, -0.05, 0.64];' 'function quantise(list, bits) {' '  const top = Math.pow(2, bits - 1) - 1;' '  const scale = Math.max(...list.map(Math.abs));' '  return list.map(function (v) { return Math.floor(v / scale * top + 0.5); });' '}' > quant.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

量子化するスクリプトを書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function restore(q, list, bits) {' '  const top = Math.pow(2, bits - 1) - 1;' '  const scale = Math.max(...list.map(Math.abs));' '  return q.map(function (n) { return n * scale / top; });' '}' >> quant.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

量子化するスクリプトを書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function worst(list, bits) {' '  const back = restore(quantise(list, bits), list, bits);' '  let w = 0;' '  list.forEach(function (v, i) { w = Math.max(w, Math.abs(v - back[i])); });' '  return w;' '}' >> quant.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

量子化するスクリプトを書く(4)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  for (const bits of [8, 4, 3, 2]) {' '    console.log(bits + \" ビット: \" + quantise(values, bits).join(\" \") + \" | 最大の誤差 \" + worst(values, bits).toFixed(4));' '  }' '  console.log(\"9.0 を一つ足した場合、4 ビット、最大の誤差 \" + worst(values.concat([9.0]), 4).toFixed(4));' '  const q = \"数をより少ないビットで保存すると何が失われるかを、短い一文で書いてください。\";' '  const sample = \"どの数も近い段に丸められるので、数どうしの小さな違いが失われます。\";' '  const reply = await ask([{ role: \"user\", content: q }], sample, 60);' '  console.log(\"返事: \" + reply.text);' '}' 'main();' >> quant.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

量子化して誤差を測る

コマンド
docker exec -w /home/node/project agent node quant.js

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

出力の例

行示していること
8 ビット: ... 最大の誤差 0.0031ほとんど何も失われない
4 ビット: 7 -3 1 4 -7 2 0 5 ...0.05 が 0 になった
2 ビット: ... 最大の誤差 0.4200小さな値の多くが消えた
9.0 を一つ足した場合 ...外れ値が一つで、誤差が大きくなる
返事: ...モデルの一文。言葉は毎回違う

学生が入力するセルは、このプレビューでは空白です。

このラボとソースについて: AI コーディングエージェントのラボ:opencode でコードを説明・修正し、その結果を確かめる

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。