llama.cppでの量子化環境構築ガイド

# llama.cppでの量子化環境構築ガイド(自分用)

## 1. 必要な環境
```bash
# 必要なツール
- Python 3.8以上
- Git
- CMake (3.16以上)
- Visual Studio 2019以上（Windowsの場合）
- CUDA Toolkit 11.7以上（GPU利用時）
```

## 2. 環境構築手順

### 2.1 基本環境のセットアップ
```bash
# 仮想環境の作成
python -m venv venv
.\venv\Scripts\activate

# 必要なパッケージのインストール
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
pip install huggingface_hub
pip install numpy
pip install sentencepiece
```

### 2.2 llama.cppのセットアップ
```bash
# リポジトリのクローン
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp

# CUDAサポート付きでビルド
mkdir build-cuda
cd build-cuda
cmake .. -DLLAMA_CUBLAS=ON
cmake --build . --config Release
```

## 3. モデルのダウンロードと変換

### 3.1 モデルダウンロードスクリプト
```python
# download_model.py
from huggingface_hub import snapshot_download
import os

def download_model(model_id, output_dir):
    """
    HuggingFaceからモデルをダウンロード
    
    Args:
        model_id (str): HuggingFaceのモデルID
        output_dir (str): 保存先ディレクトリ
    """
    try:
        local_path = snapshot_download(
            repo_id=model_id,
            local_dir=output_dir,
            ignore_patterns=["*.md", "*.txt"]
        )
        print(f"モデルを {local_path} にダウンロードしました")
        return local_path
    except Exception as e:
        print(f"エラーが発生しました: {e}")
        return None

if __name__ == "__main__":
    MODEL_ID = "mistralai/Mistral-7B-v0.1"  # 例として
    OUTPUT_DIR = "./models"
    
    if not os.path.exists(OUTPUT_DIR):
        os.makedirs(OUTPUT_DIR)
    
    download_model(MODEL_ID, OUTPUT_DIR)
```

### 3.2 GGUF変換スクリプト
```python
# convert_to_gguf.py
import os
import subprocess
import argparse

def convert_to_gguf(input_dir, output_path):
    """
    モデルをGGUF形式に変換
    
    Args:
        input_dir (str): 入力モデルのディレクトリ
        output_path (str): 出力GGUFファイルのパス
    """
    try:
        convert_script = "convert.py"  # llama.cppのconvert.pyへのパス
        
        cmd = [
            "python",
            convert_script,
            input_dir,
            "--outfile",
            output_path,
            "--outtype",
            "f16"
        ]
        
        subprocess.run(cmd, check=True)
        print(f"変換完了: {output_path}")
    except subprocess.CalledProcessError as e:
        print(f"変換エラー: {e}")
    except Exception as e:
        print(f"エラーが発生しました: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='モデルをGGUF形式に変換')
    parser.add_argument('--input', required=True, help='入力モデルのディレクトリ')
    parser.add_argument('--output', required=True, help='出力GGUFファイルのパス')
    
    args = parser.parse_args()
    convert_to_gguf(args.input, args.output)
```

### 3.3 量子化スクリプト
```python
# quantize_model.py
import os
import subprocess
import argparse

def quantize_model(input_path, output_path, quant_type="q3_K_M"):
    """
    GGUFモデルを量子化
    
    Args:
        input_path (str): 入力GGUFファイルのパス
        output_path (str): 出力（量子化済み）ファイルのパス
        quant_type (str): 量子化タイプ（q3_K_M, q4_K_M, q5_K_M等）
    """
    try:
        quantize_path = os.path.join("build-cuda", "bin", "quantize.exe")
        
        cmd = [
            quantize_path,
            input_path,
            output_path,
            quant_type
        ]
        
        subprocess.run(cmd, check=True)
        print(f"量子化完了: {output_path}")
    except subprocess.CalledProcessError as e:
        print(f"量子化エラー: {e}")
    except Exception as e:
        print(f"エラーが発生しました: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='GGUFモデルの量子化')
    parser.add_argument('--input', required=True, help='入力GGUFファイルのパス')
    parser.add_argument('--output', required=True, help='出力ファイルのパス')
    parser.add_argument('--type', default='q3_K_M', help='量子化タイプ')
    
    args = parser.parse_args()
    quantize_model(args.input, args.output, args.type)
```

## 4. 実行手順

### 4.1 モデルのダウンロードから量子化まで
```bash
# 1. モデルのダウンロード
python download_model.py

# 2. GGUF形式への変換
python convert_to_gguf.py --input ./models/mistral-7b-v0.1 --output ./models/mistral-7b-v0.1.gguf

# 3. モデルの量子化
python quantize_model.py --input ./models/mistral-7b-v0.1.gguf --output ./models/mistral-7b-v0.1-q3_K_M.gguf --type q3_K_M
```

### 4.2 バッチ処理スクリプト
```batch
@echo off
REM process_model.bat

REM 環境変数の設定
set MODEL_ID=mistralai/Mistral-7B-v0.1
set MODEL_DIR=models
set MODEL_NAME=mistral-7b-v0.1

REM 仮想環境のアクティベート
call .\venv\Scripts\activate

REM モデルのダウンロード
python download_model.py

REM GGUF形式への変換
python convert_to_gguf.py --input %MODEL_DIR%\%MODEL_NAME% --output %MODEL_DIR%\%MODEL_NAME%.gguf

REM モデルの量子化
python quantize_model.py --input %MODEL_DIR%\%MODEL_NAME%.gguf --output %MODEL_DIR%\%MODEL_NAME%-q3_K_M.gguf --type q3_K_M

echo 処理が完了しました
pause
```

## 5. トラブルシューティング

### 5.1 一般的な問題
1. メモリ不足エラー
   - 十分な空きメモリ（RAM）があることを確認
   - 他のアプリケーションを終了
   - 必要に応じてページファイルサイズを増加

2. CUDA関連エラー
   - CUDA Toolkitのバージョンを確認
   - `nvidia-smi`でGPUの状態を確認
   - ドライバーの更新を検討

3. Python依存関係エラー
   - 仮想環境が正しくアクティベートされているか確認
   - `pip list`で必要なパッケージがインストールされているか確認

### 5.2 エラーログの確認
```bash
# CUDA情報の確認
nvidia-smi

# Python環境の確認
pip list
python --version

# llama.cppのビルド情報
cmake --version
```

## 6. パフォーマンス最適化

### 6.1 メモリ使用量の監視
```python
# memory_monitor.py
import psutil
import GPUtil
import time

def monitor_resources():
    while True:
        # CPU・メモリ使用率
        cpu_percent = psutil.cpu_percent()
        memory = psutil.virtual_memory()
        
        # GPU情報
        gpus = GPUtil.getGPUs()
        for gpu in gpus:
            print(f"\nGPU {gpu.id} - {gpu.name}")
            print(f"Memory Use: {gpu.memoryUsed}MB / {gpu.memoryTotal}MB")
            print(f"GPU Load: {gpu.load*100}%")
        
        print(f"\nCPU使用率: {cpu_percent}%")
        print(f"メモリ使用率: {memory.percent}%")
        print("-" * 50)
        
        time.sleep(1)

if __name__ == "__main__":
    monitor_resources()