(rontolisp) docs
← rontolisp パッケージの関数

rontolisp:quantize

(rontolisp:quantize array format)

パックされた浮動小数点配列(single-float、double-float、bfloat16。階数 1 か 2、 最後の次元は 32 の倍数)を format の量子化行列に量子化します。形式は q8-0、 ggml の Q8_0 の一つだけです。32 要素のブロックごとに binary16 のスケール d と 符号付き 8 ビットの量子 32 個を持ち、値は q * d、1 要素あたり 1.0625 バイトです。 算術は ggml 自身の quantize_row_q8_0_ref そのもの(ブロックの f32 絶対値最大、 d = amax / 127、各量子は round(x / d) で同点は 0 から遠い側へ、d は binary16 に 丸める)なので、同じ値に対して llama-quantize が書くバイト列を保持し、 write-sequence した結果は llama.cpp が読み戻せる Q8_0 テンソルです。

量子化行列は配列ではなく独自の型です。aref と row-major-aref は逆量子化した q * d を double で返し、(setf aref) はエラーになります(要素には自分のスロットが なく、1 要素を書くにはブロックごと再量子化が要る)。array-dimensions / array-rank / array-total-size は使え、array-element-type は形式シンボル q8-0 を返し、arrayp は nil、 rontolisp:quantized-matrix-p と (typep x 'rontolisp:quantized-matrix) が判定します。印字は #<quantized-matrix q8-0 (rows cols)> で、リテラル構文はありません。

上の 2 行は絶対値最大が 127 なので d はちょうど 1 で、すべての値がそのまま残ります。 一般には値は最大で量子の半分、amax / 254 だけ動きます。

vec:matvec と vec:matvec-into は行列として量子化行列を受け取り、#f または #d のベクタに対して ggml の整数内積の形(活性値を 32 要素ブロックごとに int8 へ量子化し、ブロックごとに 4 レーンの厳密な整数和、レーンごとに 1 回の double 積和を 4 つのアキュムレータへ)で計算します。これはインタプリタと JVM、--simd / --parallel の有無を問わずビット 単位で同じ値です。他の vec: / linalg: 操作はパックされた浮動小数点配列を要求する ので、先に rontolisp:dequantize してください(例外は linalg:row で、量子化行列の 1 行をそのまま #f ベクタに読み出します)。量子化した 積は f32 の積に対して量子化誤差(公開重みで相対 8e-3 程度)だけ離れており、丸め誤差 ではありません。Q8_0 モデルが出す数は、同じファイルから llama.cpp が出す数であって、 BF16 ファイルが出す数ではありません。

インタプリタと JVM のみ。両方の WASM バックエンドは rontolisp:quantize と rontolisp:dequantize をコンパイル時に拒否します。--gpu と --blas はこの型を 辞退し、レーンカーネルかスカラー defun が答えます。gguf:read は Q8_0 テンソルから この関数を経由せずに量子化行列を作ります。