跳至主要内容

CLI 參考

TinyLoop 提供單一 CLI 可執行檔:

tinyloop <model.tinyloop> <command> [options]

目前指令:

  • inspect
  • benchmark
  • generate
  • speculate

全域形式

./tinyloop/build/tinyloop /path/to/model.tinyloop <command> ...

模型路徑永遠是可執行檔名稱後的第一個參數。

inspect

讀取 metadata 與記憶體估算,不需把完整權重載入 GPU。

用法

./tinyloop/build/tinyloop model.tinyloop inspect

會輸出什麼

  • 格式版本
  • 量化 bit 寬
  • 維度與 head 數量
  • embedding 模式
  • 權重大小估算
  • 常見序列長度的 buffer 估算
  • KV-cache 估算
  • 相對粗略 FP16 baseline 的壓縮比較

使用情境

  • 快速驗證 artifact
  • 記憶體規劃
  • converter 健全性檢查

benchmark

重複執行前向計算並回報延遲與吞吐。

用法

./tinyloop/build/tinyloop model.tinyloop benchmark \
--loops 8 \
--seq-len 128 \
--repeat 10

選項

Flag意義預設值
--loops執行時 loop 次數8
--seq-len合成 token 長度512
--repeat計時迭代次數20

注意事項

  • 這條路徑測的是前向 scoring,不是生成吞吐
  • 設定 TINYLOOP_CUDA_PROFILE=1 時會略過 warmup
  • benchmark 使用虛擬 token id,只用於 runtime 測量

generate

從 prompt 生成續文。

用法

./tinyloop/build/tinyloop model.tinyloop generate \
--prompt "Looped transformers are" \
--loops 8 \
--max-tokens 32 \
--temperature 0.8 \
--top-k 50 \
--cache-window 0

選項

Flag意義預設值
--prompt輸入 prompt 字串"The meaning of life is"
--loops生成用 loop 次數8
--max-tokens新增 token 數量128
--temperature取樣溫度0.8
--top-kTop-k 截斷50
--cache-windowSliding-window KV 大小,0 代表完整快取0
--l-warmup-tokens NL 排程(架構獨有):前 N 個 decode step 以 --l-warmup-L 深度執行。攤提計算 — 容易的初始 token 用淺層 pass,後續 token 用完整深度。0(停用)
--l-warmup-L NL 排程 warmup 階段的 loop 深度。2

目前行為

  • cached decode 預設開啟
  • CLI 會把 prompt 文字視為 raw bytes tokenization
  • runtime 會配置 max_seq = prompt_bytes + max_tokens

偵錯參考路徑

強制 uncached generation:

TINYLOOP_DISABLE_KV_CACHE=1 \
./tinyloop/build/tinyloop model.tinyloop generate --prompt "Hello"

停用新版 tiled prefill attention 路徑:

TINYLOOP_DISABLE_FLASH2_PREFILL=1 \
./tinyloop/build/tinyloop model.tinyloop generate --prompt "Hello"

speculate

使用同一模型做 draft 與 verify 的自我推測式解碼。

用法

./tinyloop/build/tinyloop model.tinyloop speculate \
--prompt "Looped transformers are" \
--draft-loops 2 \
--verify-loops 8 \
--draft-ahead 4 \
--max-tokens 32 \
--temperature 0.0 \
--top-k 50 \
--top-p 0.9 \
--cache-window 0

選項

Flag意義預設值
--prompt輸入 prompt 字串"The meaning of life is"
--draft-loopsDraft loop 次數2
--verify-loopsVerify loop 次數8
--draft-ahead每輪草擬 token 數4
--max-tokens最大生成 token 數50
--temperature取樣溫度0.0
--top-kTop-k 截斷50
--top-pTop-p 截斷0.9
--cache-windowSliding-window KV 大小0

Environment variables

變數意義
TINYLOOP_LOG_LEVEL=NRuntime 日誌層級。0 靜默(錯誤仍輸出 stderr),1 預設(保留模型 header、VRAM 摘要、L2 residency 行),2 加上逐元件載入細節、buffer allocator 註記與 cache warmup 行。超出 [0, 2] 範圍的值會回退到 1
TINYLOOP_CUDA_PROFILE=1benchmark 期間輸出分段時間
TINYLOOP_DISABLE_KV_CACHE=1強制 uncached generation
TINYLOOP_EXPERIMENTAL_FP16_BODY=1載入時將 body 權重反量化成 FP16 cache,之後所有 body GEMM 都走 cuBLAS tensor core(Ampere 用 WMMA,Hopper 用 WGMMA)。2026-04-17 於 H100 / 407M INT4 實測:prefill 快 30-65 倍(如 seq=128 183→2.8 ms,seq=1024 1431→48 ms),decode 快約 2.4 倍(1241→514 ms / 128 tokens)。權重 VRAM 會放大約 2.9 倍(407M 為 216 → 619 MB)— VRAM 夠再開,不夠就關。由於 FP16 tensor core 的 rounding path 與我們 INT4 scalar-FP32 reference 不同,輸出會在幾個 token 後 diverge — 兩邊都屬於量化模型的合法取樣。
TINYLOOP_KV_INT8=1把 KV cache 存成 per-token per-head 對稱 INT8,每個 (token, head) 帶 1 個 FP16 scale。2026-04-17 於 H100 / 407M INT4 max_seq=2048 實測:KV footprint 從 167.8 MB 降到 85.2 MB(−49%),同 VRAM budget 現在能塞 ~4k tokens 的 context(之前 ~2k)。Greedy 輸出在前 ~40 tokens 與 FP16 KV 完全相同,之後隨 INT8 rounding 累積而分歧 — 兩邊都是合法取樣。decode 分別退步 +3.6% / +9.1% / +13.6% 於 seq ∈ 2048。可與 TINYLOOP_EXPERIMENTAL_FP16_BODY=1 疊加。
TINYLOOP_CROSS_ITER_ROUND=1啟用 §16.9 cross-iteration stochastic rounding。dispatcher 會把 INT4 GEMM 路由到 int4_gemm_stoch_frac4(優先)或 int4_gemm_stoch_1bit(後備),前提是載入的 .tinyloop 是 v5+ 且 weight 有對應的 sign-bit 或 4-bit frac channel。每個 loop iteration 透過 PCG-hash 抽一個 seed,同一個 weight 跨 L 次 iteration 產生略微不同的有效值 — 誤差 zero-mean,累積速率從 naïve INT4 的 O(L) 降到 O(√L)。需要用 tools/tinyloop_add_sign_bit.py --from-pt PATH --loop-only [--frac-bits {1,4}] 產生 v5 檔。2026-04-17 於 407M / WikiText-103 val 實測:L=16 時 stoch_frac4 比 naïve INT4 好 −0.32 PPL,L=32 時好 −0.67 PPL(paper §R.10)。預設關閉;沒有 sign-bit channel 的模型上零成本。
TINYLOOP_KV_H_MODE=1§16.14.b Phase 1A — iteration-axis KV 壓縮的 parity harness。 啟用時,runtime 會在每個 cache layer 額外配置一個 FP16 buffer(h_cache,形狀同 k_cache),並在每次 prefill 與 decode append 時把 QKV 前的 LayerNorm 輸出寫進去。Phase 1A 仍保留 FP16 K/V buffer 與寫入(目前沒有節省記憶體 — 僅 parity)。適用於測試與研究工具(tests/test_kv_h_modetools/measure_trajectory.py)需要在 cache 中取得每 token、每 iteration hidden state 以研究 delta-coding / store-$h$-recompute 方案。Phase 1B 會在此旗標開啟時關掉 K/V 配置,改以 block 的 attn_qkv 從儲存的 $h$ 重建 K/V。預設關閉;未使用時零 runtime 成本。
TINYLOOP_DISABLE_FLASH2_PREFILL=1停用較新的 tiled prefill attention 路徑
TINYLOOP_DISABLE_CUBLAS_FP16=1停用 cuBLAS 後端 FP16 GEMM
TINYLOOP_USE_CUDNN_SDPA=1將 prefill attention(T > 1)走 cuDNN SDPA graph。在 Hopper (SM90) 內部會解析為 FlashAttention-3 kernel,在 Ampere (SM80) 為 FA-2。build 時需要 cuDNN 9+(自動偵測 nvidia-cudnn-cu12 / nvidia-cudnn-frontend pip wheel)。若 plan 建置或執行失敗會靜默 fallback 回 attention_flash2。預設關閉 — 在 407M INT4 上 end-to-end 增益很小,因為 INT4 GEMM 才是主要瓶頸;在 attention 佔比較大的配置(更長的 seq_len、BF16/FP8 body 等)才會明顯勝出。
TINYLOOP_TOKEN_EXIT=N在 scoring 啟用 token-stable early-exit 探測
TINYLOOP_TOKEN_EXIT_VERBOSE=1輸出 early-exit 診斷資訊

CLI 目前還不是什麼

目前 CLI 限制:

  • 不是 tokenizer-first 介面
  • 不是伺服器
  • 不是 batching 介面
  • 不是面向多 checkpoint 家族的最終相容性契約