最適な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>

コメント