最適なGGUFモデルを教えてくれるツール


画像

・ソースコードはこちら。↓

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>GGUFモデル最適化ツール (拡張版)</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 600px; margin: 20px auto; padding: 20px; background: #f8f9fa; }
        form { display: grid; gap: 15px; }
        label { font-weight: bold; }
        input, select { padding: 10px; border: 1px solid #ccc; border-radius: 6px; font-size: 16px; }
        button { padding: 12px; background: #007bff; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 16px; }
        button:hover { background: #0056b3; }
        #result { margin-top: 25px; padding: 20px; border: 1px solid #ddd; border-radius: 8px; background: white; white-space: pre-wrap; line-height: 1.5; }
        .hidden { display: none; }
    </style>
</head>
<body>
    <h1>GGUFモデル最適化ツール (拡張版)</h1>
    <p>PCスペックとモデルを選択すると、最適なGGUFクアンタとllama.cppオプションを提案します。幅広いモデル対応。</p>
    
    <form id="specForm">
        <div>
            <label for="model">対象モデル:</label>
            <select id="model" required>
                <option value="">選択してください</option>
                <option value="llama3.1-8b">Llama3.1-8B (Dense, 8B params)</option>
                <option value="mistral-7b">Mistral-7B (Dense, 7B params)</option>
                <option value="gemma2-9b">Gemma-2-9B (Dense, 9B params)</option>
                <option value="phi3-3.8b">Phi-3-3.8B (Dense, 3.8B params)</option>
                <option value="qwen3.5-7b">Qwen3.5-7B (Dense, 7B params)</option>
                <option value="qwen3.5-27b">Qwen3.5-27B (Dense, 27B params)</option>
                <option value="qwen3.5-35b-a3b">Qwen3.5-35B-A3B (MoE, 35B/Active 3B)</option>
                <option value="llama3.1-70b">Llama3.1-70B (Dense, 70B params)</option>
                <!-- 必要に応じて追加可能 -->
            </select>
        </div>
        
        <div>
            <label for="quant">GGUFクアンタ (任意: 自動推奨以外指定):</label>
            <select id="quant">
                <option value="auto">自動推奨</option>
                <option value="Q2_K">Q2_K (低品質・軽量)</option>
                <option value="IQ3_XXS">IQ3_XXS (低品質・効率)</option>
                <option value="Q3_K_S">Q3_K_S (バランス)</option>
                <option value="Q3_K_M">Q3_K_M (バランス)</option>
                <option value="Q4_K_S">Q4_K_S (中品質)</option>
                <option value="Q4_K_M">Q4_K_M (中品質・人気)</option>
                <option value="IQ4_XS">IQ4_XS (中品質・効率)</option>
                <option value="Q5_K_S">Q5_K_S (高品質)</option>
                <option value="Q5_K_M">Q5_K_M (高品質)</option>
                <option value="Q6_K">Q6_K (高品質)</option>
                <option value="Q8_0">Q8_0 (最高品質)</option>
            </select>
        </div>
        
        <div>
            <label for="ram">メインメモリ容量 (GB):</label>
            <input type="number" id="ram" min="1" step="1" placeholder="例: 32" required>
        </div>
        
        <div>
            <label for="storageType">ストレージタイプ:</label>
            <select id="storageType" required>
                <option value="">選択してください</option>
                <option value="SSD">SSD</option>
                <option value="HDD">HDD</option>
            </select>
        </div>
        
        <div>
            <label for="storageSize">ストレージ空き容量 (GB):</label>
            <input type="number" id="storageSize" min="1" step="1" placeholder="例: 2000" required>
        </div>
        
        <div>
            <label for="hasGpu">GPUの有無:</label>
            <select id="hasGpu" required>
                <option value="">選択してください</option>
                <option value="yes">あり</option>
                <option value="no">なし</option>
            </select>
        </div>
        
        <div id="vramGroup" class="hidden">
            <label for="vram">GPUビデオメモリ容量 (GB):</label>
            <input type="number" id="vram" min="1" step="1" placeholder="例: 12">
        </div>
        
        <button type="submit">Calculate</button>
    </form>
    
    <div id="result"></div>

    <script>
        const form = document.getElementById('specForm');
        const hasGpu = document.getElementById('hasGpu');
        const vramGroup = document.getElementById('vramGroup');
        const vramInput = document.getElementById('vram');
        const resultDiv = document.getElementById('result');
        const modelSelect = document.getElementById('model');
        const quantSelect = document.getElementById('quant');

        // モデルごとのデータ (総パラメータ, MoEフラグ, Q4_K_M目安サイズGB)
        const modelData = {
            'llama3.1-8b': { params: 8, isMoE: false, q4Size: 4.9 },
            'mistral-7b': { params: 7, isMoE: false, q4Size: 4.5 },
            'gemma2-9b': { params: 9, isMoE: false, q4Size: 5.2 },
            'phi3-3.8b': { params: 3.8, isMoE: false, q4Size: 2.8 },
            'qwen3.5-7b': { params: 7, isMoE: false, q4Size: 4.6 },
            'qwen3.5-27b': { params: 27, isMoE: false, q4Size: 15 },
            'qwen3.5-35b-a3b': { params: 35, isMoE: true, q4Size: 20 },
            'llama3.1-70b': { params: 70, isMoE: false, q4Size: 38 }
        };

        // クアンタごとのサイズ倍率目安 (Q4_K_Mを1.0基準)
        const quantSizes = {
            'Q2_K': 0.6,
            'IQ3_XXS': 0.65,
            'Q3_K_S': 0.75,
            'Q3_K_M': 0.8,
            'Q4_K_S': 0.9,
            'Q4_K_M': 1.0,
            'IQ4_XS': 0.95,
            'Q5_K_S': 1.1,
            'Q5_K_M': 1.15,
            'Q6_K': 1.3,
            'Q8_0': 1.7
        };

        // クアンタごとの品質レベル
        const quantQuality = {
            'Q2_K': '低 (出力崩れやすい)',
            'IQ3_XXS': '低 (効率重視)',
            'Q3_K_S': '中 (バランス)',
            'Q3_K_M': '中 (バランス)',
            'Q4_K_S': '中高 (人気)',
            'Q4_K_M': '中高 (人気)',
            'IQ4_XS': '中高 (効率)',
            'Q5_K_S': '高 (おすすめ)',
            'Q5_K_M': '高 (おすすめ)',
            'Q6_K': '高 (近フル品質)',
            'Q8_0': '最高 (近フル品質)'
        };

        hasGpu.addEventListener('change', () => {
            if (hasGpu.value === 'yes') {
                vramGroup.classList.remove('hidden');
                vramInput.required = true;
                vramInput.disabled = false;
            } else {
                vramGroup.classList.add('hidden');
                vramInput.required = false;
                vramInput.disabled = true;
                vramInput.value = '';
            }
        });

        form.addEventListener('submit', (e) => {
            e.preventDefault();
            if (!form.checkValidity()) {
                form.reportValidity();
                return;
            }

            const selectedModel = modelSelect.value;
            const modelInfo = modelData[selectedModel];
            const selectedQuant = quantSelect.value;
            const ram = parseInt(document.getElementById('ram').value) || 0;
            const storageType = document.getElementById('storageType').value;
            const storageSize = parseInt(document.getElementById('storageSize').value) || 0;
            const gpu = hasGpu.value;
            const vram = gpu === 'yes' ? parseInt(vramInput.value) || 0 : 0;

            // 推奨クアンタ計算 (自動時)
            let recommendedQuant = selectedQuant === 'auto' ? 'Q3_K_M' : selectedQuant;
            let fileSizeEst = modelInfo.q4Size * (quantSizes[recommendedQuant] || 1.0); // 目安ファイルサイズ
            let llamaOptions = '--parallel 1 -c 8192 --temp 1.0 --top-k 20 --top-p 0.95 --min-p 0';
            let notes = '';
            let speedEst = '10-20'; // tok/s目安
            let qualityLevel = quantQuality[recommendedQuant];

            if (gpu === 'yes') {
                // VRAMに基づく推奨調整 (自動時)
                if (selectedQuant === 'auto') {
                    if (vram >= 24) {
                        recommendedQuant = modelInfo.params > 30 ? 'Q4_K_M' : 'Q5_K_M';
                    } else if (vram >= 16) {
                        recommendedQuant = modelInfo.params > 30 ? 'Q3_K_M' : 'Q4_K_M';
                    } else if (vram >= 10) {
                        recommendedQuant = 'Q3_K_S';
                    } else if (vram >= 6) {
                        recommendedQuant = 'Q2_K';
                    } else {
                        recommendedQuant = 'IQ3_XXS';
                    }
                    fileSizeEst = modelInfo.q4Size * (quantSizes[recommendedQuant] || 1.0);
                }

                // オプション調整 (指定クアンタ考慮)
                if (fileSizeEst + 2 > vram) { // +2GB for KV cache
                    notes += '\n⚠ VRAM超過の可能性 → CPUオフロード多め';
                    llamaOptions += ' -ngl 40'; // 部分GPU
                    speedEst = '5-15';
                } else {
                    llamaOptions += ' -ngl 99 --flash-attn';
                    speedEst = modelInfo.isMoE ? '20-35' : '25-50';
                }

                // MoE特有
                if (modelInfo.isMoE) {
                    llamaOptions += ' -ot ".ffn_.*_exps.=CPU"'; // expert offload
                    notes += '\nMoEモデル → expertをCPUへ逃がすオプション追加';
                    if (selectedQuant !== 'auto' && ['Q2_K', 'IQ3_XXS'].includes(recommendedQuant)) {
                        notes += '\n低クアンタ指定 → 出力が不安定になる可能性。Q3以上推奨';
                    }
                } else if (selectedQuant !== 'auto') {
                    if (recommendedQuant.startsWith('Q6') || recommendedQuant === 'Q8_0') {
                        notes += '\n高クアンタ指定 → VRAM多用。フルGPUで高速';
                        speedEst += '+ (高品質で速い)';
                    } else if (recommendedQuant.startsWith('Q2') || recommendedQuant === 'IQ3_XXS') {
                        notes += '\n低クアンタ指定 → 品質低下。CPU多用で速度低下';
                        llamaOptions = llamaOptions.replace('--parallel 1', '--parallel 4'); // denseならparallel上げOK
                        speedEst = '5-10';
                    }
                }
            } else {
                recommendedQuant = selectedQuant === 'auto' ? 'Q2_K' : recommendedQuant;
                llamaOptions += ' -t 12 --mlock';
                notes += '\nGPUなし → CPUメイン。速度遅め';
                speedEst = '3-10';
            }

            // RAM/ストレージ警告
            if (ram < 16) notes += '\n⚠ RAM少ない → --mlock OFF推奨、スワップ注意';
            if (storageType === 'HDD') notes += '\n⚠ HDD → ロード遅い (SSD推奨)';
            if (storageSize < fileSizeEst * 1.5) notes += `\n⚠ 空き容量不足 → GGUF目安${fileSizeEst.toFixed(1)}GB必要`;

            resultDiv.innerHTML = `
<b>対象モデル:</b> ${selectedModel.toUpperCase()} (${modelInfo.isMoE ? 'MoE' : 'Dense'}, ${modelInfo.params}B params)

<b>GGUFクアンタ:</b> ${recommendedQuant} (品質: ${qualityLevel}, ファイルサイズ目安: ${fileSizeEst.toFixed(1)}GB)

<b>推奨llama.cppオプション例:</b>
./llama-server -m model.gguf --jinja ${llamaOptions}  # (Qwen系は--jinja必須。他モデルは任意)

<b>目安速度 (tok/s):</b> ${speedEst} (RTX3060相当で8k ctx時)

<b>追加アドバイス:</b>
${notes}
            `;
        });
    </script>
</body>
</html>

いいなと思ったら応援しよう!

コメント

コメントするには、 ログイン または 会員登録 をお願いします。
最適なGGUFモデルを教えてくれるツール|古井和雄
word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word

mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1