科学と神々株式会社アドベントカレンダー 2025
LLM量子化 Day 20: CLI設計
良いCLIとは何か
コマンドラインツールの品質は、技術的な機能だけでなく、ユーザー体験に大きく依存します。llm-quantizeは、以下の原則に基づいてCLIを設計しています:
1. 予測可能性
ユーザーが「こう動くだろう」と思った通りに動く。
2. 発見可能性
--helpを見れば、何ができるかがわかる。
3. スクリプト親和性
シェルスクリプトやパイプラインに組み込みやすい。
Clickフレームワークの採用
PythonのCLI開発には多くの選択肢があります:
| ライブラリ | 特徴 |
|---|---|
| argparse | 標準ライブラリ、基本機能 |
| Click | デコレータベース、高機能 |
| Typer | Clickベース、型ヒント活用 |
| Fire | 関数を自動的にCLI化 |
llm-quantizeはClickを採用しました。理由は:
- デコレータによる宣言的な定義: コードが読みやすい
- コンテキスト管理: グローバル設定の共有が容易
-
サブコマンド:
gitのような階層構造を自然に表現 - 型変換: 引数の自動変換とバリデーション
コマンド構造の設計
llm-quantize
├── --format [human|json] # グローバルオプション
├── --verbosity [quiet|normal|verbose|debug]
├── --version
├── --help
│
├── quantize # メインコマンド
│ ├── MODEL # 位置引数
│ ├── FORMAT # 位置引数(gguf|awq|gptq)
│ ├── -q, --quantization # 量子化レベル
│ ├── -o, --output # 出力先
│ └── --group-size # グループサイズ
│
├── convert # 変換コマンド
│ ├── SOURCE # 変換元
│ ├── TARGET_FORMAT # 変換先形式
│ ├── -o, --output # 出力先
│ └── --force # 上書き許可
│
└── info # 情報表示
└── MODEL # モデル指定
終了コードの設計
UNIXの慣習に従い、成功時は0、失敗時は非ゼロを返します:
| コード | 意味 | 例 |
|---|---|---|
| 0 | 成功 | 量子化完了 |
| 1 | 一般エラー | 予期しない例外 |
| 2 | 引数エラー | 無効なオプション |
| 3 | モデル未発見 | パスが存在しない |
| 4 | 認証必要 | HuggingFaceログイン要 |
| 5 | メモリ不足 | OOMエラー |
| 6 | 検証失敗 | 出力ファイル破損 |
| 7 | チェックポイントエラー | 再開不可 |
これにより、スクリプトで適切にエラーハンドリングできます:
llm-quantize quantize model gguf -q Q4_K_M
status=$?
case $status in
0) echo "Success!" ;;
3) echo "Model not found. Check the path." ;;
5) echo "Out of memory. Try smaller model or reduce batch size." ;;
*) echo "Error: exit code $status" ;;
esac
出力モードの設計
llm-quantizeは2つの出力モードをサポートします:
Human モード(デフォルト)
$ llm-quantize quantize model gguf -q Q4_K_M
Quantizing to GGUF Q4_K_M...
[████████████████████████████████] 100%
✓ Quantization complete
Output: model-Q4_K_M.gguf
Size: 4.0 GB
Compression: 72%
カラフルで読みやすい出力。対話的な使用に最適。
JSON モード
$ llm-quantize --format json quantize model gguf -q Q4_K_M
{
"status": "success",
"output_path": "model-Q4_K_M.gguf",
"file_size": 4294967296,
"compression_ratio": 0.72
}
機械可読な出力。スクリプトやパイプラインでの使用に最適。
# JSON出力をjqでパース
output=$(llm-quantize --format json info model)
params=$(echo "$output" | jq '.parameter_count')
echo "Model has $params parameters"
コンテキストの共有
Clickのコンテキスト機能を使って、グローバル設定を共有します:
メインコマンド
├── output_format: human/json
├── verbosity: quiet/normal/verbose/debug
└── console: Richコンソール
│
└── サブコマンドに自動的に渡される
├── quantize
├── convert
└── info
これにより、各サブコマンドは共通の設定にアクセスできます。
ヘルプメッセージの設計
良いヘルプメッセージは、ユーザーが困ったときの道標です:
$ llm-quantize --help
Usage: llm-quantize [OPTIONS] COMMAND [ARGS]...
LLM-Quantize: A unified CLI tool for LLM model quantization.
Options:
--format [human|json] Output format: human (default), json
--verbosity [quiet|normal|verbose|debug]
Log level: quiet, normal (default), verbose, debug
--version Show the version and exit.
--help Show this message and exit.
Commands:
convert Convert between quantization formats
info Display model information
quantize Quantize a model to the specified format
$ llm-quantize quantize --help
Usage: llm-quantize quantize [OPTIONS] MODEL FORMAT
Quantize a model to the specified format.
Arguments:
MODEL Model path or HuggingFace model ID [required]
FORMAT Target format: gguf, awq, gptq [required]
Options:
-q, --quantization TEXT Quantization level (e.g., Q4_K_M, 4bit) [required]
-o, --output PATH Output directory [default: .]
--group-size INTEGER Group size for quantization [default: 128]
--help Show this message and exit.
エラーメッセージの設計
エラーメッセージは、問題の原因と解決策を明示します:
# 悪い例
Error: Invalid argument
# 良い例
Error: Model not found: /path/to/model
Please check:
1. The path exists
2. You have read permissions
3. If using HuggingFace ID, run 'huggingface-cli login' first
バリデーションのタイミング
引数のバリデーションは、できるだけ早く行います:
コマンド受信
│
▼ 引数パース(Click)
│ - 必須引数のチェック
│ - 型変換
│
▼ カスタムバリデーション
│ - モデルパスの存在確認
│ - 量子化レベルの妥当性
│ - 出力先の書き込み権限
│
▼ 処理開始
│ - この時点で引数は確実に有効
長時間処理の途中でエラーになるのは最悪です。開始前にすべて検証しましょう。
Tips: CLIデザインのコツ
1. デフォルト値を賢く選ぶ
# 多くのユーザーに適した値をデフォルトに
--group-size 128 # ほとんどの場合にバランスが良い
--verbosity normal # 必要十分な情報量
2. 短縮形を提供する
# 長い形式
llm-quantize quantize model gguf --quantization Q4_K_M --output ./output
# 短縮形(頻繁に使うオプションのみ)
llm-quantize quantize model gguf -q Q4_K_M -o ./output
3. 一貫性を保つ
# すべてのコマンドで出力先は -o
llm-quantize quantize model gguf -q Q4_K_M -o ./output
llm-quantize convert model.gguf awq -o ./output
4. 進捗を示す
# 長時間処理では進捗表示が必須
Quantizing layer 15/32 [████████████ ] 47%
5. 確認プロンプトは慎重に
# 対話的プロンプトはスクリプトを壊す
# --forceオプションで回避可能にする
Output already exists. Overwrite? [y/N]
# スクリプトでは --force で自動承認
llm-quantize convert model.gguf awq -o ./output --force
次回予告
Day 21では「プログレス表示」として、Richライブラリを使った視覚的なフィードバックの実装について解説します。
CLIは「ユーザーとの最初の接点」です。技術的に優れた機能も、使いにくいインターフェースでは価値が半減します。UXを意識したCLI設計は、ツールの普及に直結します。