長文ですが、誰かの役に立てばうれしいです。Llama-cppのVulkanサーバーを単一のAMD R9700で動かしています。以下の設定は、ChatGPTが私にくれたテスト用のWebサイトを生成するための大きなプロンプトで非常に良い結果を出しました。その後、Playwrightのテスト一式を生成するプロンプトを実行しました。
テスト作成時に、1つの失敗テストを1回ずつ修正するように一度だけ促す必要がありました。Webサイトは初回実行で完全に機能していました。
(次の大きなリリースまでの間は)モデルの調整とテストはこれで終わりだと思うので、今はまたコーディングに戻れます…
llama-cpp | ========== LLAMA.CPP STARTUP COMMAND ========== llama-cpp | /app/llama-server -m /models/Qwen3.6-35B-A3B-UD-Q5_K_XL/Qwen3.6-35B-A3B-UD-Q5_K_XL.gguf --ctx-size 262144 --threads 8 --threads-batch 8 --gpu-layers 99 --parallel 1 --flash-attn on --batch-size 2048 --ubatch-size 1024 --cache-type-k q8_0 --cache-type-v q8_0 --cache-ram 12000 --ctx-checkpoints 50 --mmap --no-mmproj --kv-unified --reasoning off --reasoning-budget 0 --jinja --temp 0.6 --top-k 20 --top-p 0.95 --min-p 0.0 --repeat-penalty 1.0 --presence-penalty 0.0 サンプリングの設定は https://huggingface.co/Qwen/Qwen3.6-35B-A3B の「precise coding」セクションにあります。
VS Code chatLanguageModels.json :
{ "name": "Sean Llama.cpp", "vendor": "customoai", "apiKey": "${input:chat.lm.secret.3c0c0f21}", "models": [ { "id": "Qwen3.6-35B-A3B-UD-Q5_K_XL.gguf", "name": "Qwen3.6-35B", "url": "https://llm.home.arpa/v1/chat/completions", "toolCalling": true, "vision": false, "maxInputTokens": 180000, "maxOutputTokens": 10000, "family": "Qwen3", "inputTokenCost": 0.0001, "outputTokenCost": 0.0001, "temperature": 0.6, "top_p": 0.95, "top_k": 20, "repeat_penalty": 1, "presence_penalty": 0, "frequency_penalty": 0, "systemMessage": "You are a precise coding assistant. Avoid repeating plans. Execute tasks directly. Do not restate intentions multiple times.", "timeout": 600000, "retry": { "enabled": true, "max_attempts": 2, "interval_ms": 1500 } } ] } ChatGPTが生成したテスト用プロンプト :
You are working in a clean Vite + React + TypeScript project. Your task is to build a medium-complexity local-first website called “Bike Shop Service Tracker.” The app should help a small bike shop track incoming bike repair jobs. It should run entirely in the browser using localStorage. Do not use a backend, database, authentication, external API, router, Tailwind, shadcn, Redux, Zustand, or any complex setup. Use only: - React - TypeScript - plain CSS or CSS modules - browser localStorage - lucide-react only if already installed Before implementing, inspect the existing project structure briefly. Then create a concise implementation plan. After the plan, implement the app directly. Do not get stuck repeating the plan. Functional requirements: 1. Main layout - Create a polished single-page dashboard. - Header with app name: “Bike Shop Service Tracker.” - A summary area showing: - total open jobs - jobs due today - overdue jobs - completed jobs - Main content split into: - job creation/edit form - job list and filters 2. Repair job data model Each repair job should include: - id - customerName - customerPhone - bikeDescription - serviceType - priority: low, normal, high, urgent - status: intake, waiting-parts, in-progress, ready, completed - dueDate - notes - createdAt - updatedAt 3. Seed data - If localStorage is empty, create 6 realistic sample repair jobs. - Include different statuses, priorities, due dates, and service types. - Make at least one job overdue and one job due today. 4. Job form - Allow creating a new job. - Allow editing an existing job. - Include basic validation: - customer name required - phone required - bike description required - service type required - due date required - Show clear validation messages. - Include buttons: - Save Job - Cancel Edit, when editing - Clear Form 5. Job list - Display jobs as cards or table rows. - Each job should show: - customer name - bike description - service type - priority - status - due date - notes preview - Include actions: - edit - mark completed - delete 6. Filtering and sorting Add controls for: - search by customer name, phone, bike description, service type, or notes - filter by status - filter by priority - sort by due date - sort by priority - sort by created date 7. UX behavior - Persist all jobs to localStorage. - Keep the UI responsive and usable on desktop and narrow screens. - Use clear visual differences for priority and status. - Completed jobs should look visually quieter than active jobs. - Overdue jobs should be visually obvious. - Due-today jobs should be highlighted differently from overdue jobs. - Deleting a job should ask for confirmation. 8. Code organization Create a reasonable file structure, for example: - src/App.tsx - src/App.css - src/types.ts - src/data/seedJobs.ts - src/utils/storage.ts - src/utils/jobFilters.ts - src/components/JobForm.tsx - src/components/JobList.tsx - src/components/JobCard.tsx - src/components/SummaryCards.tsx - src/components/FilterBar.tsx Use this structure only if it makes sense. Do not over-engineer. 9. Quality requirements - TypeScript should compile cleanly. - Avoid `any` unless there is a strong reason. - Keep functions readable. - Avoid huge components where possible. - The app should run with: npm run dev 10. Final response When finished, summarize: - what files were created or changed - how to run the app - what features were implemented - any limitations or follow-up improvements Important behavior instructions: - Do not only create todos. - Do not repeatedly say “I need to implement this now.” - Do not repeatedly read the same files unless needed. - Once you have enough context, start editing files. - Prefer completing a working first version over designing a perfect architecture. Llamaのログをローカルのqwenにフィードバック(少し皮肉ですね)したところ、大成功した大規模なコパイロット/オートパイロットのセッションからの、自己パフォーマンスの要約を次のように返してきました:
プロンプト:これらのllama.cppログを分析して、パフォーマンスの見え方を教えてください:
提供されたログに基づくと、あなたの llama.cpp インスタンスの詳細なパフォーマンス分析は以下のとおりです。
エグゼクティブサマリー
- 全体の状態: 良好/健康的。 サーバーは正しく機能しており、クラッシュやハングなしでリクエストを処理しています。
- スループット: 中程度。 生成のための速度として、だいたい 94〜105トークン/秒 (t/s) が見えています。これは、実行しているハードウェアモデル(GGUFの量子化)によって異なりますが、中価格帯のコンシューマ向けGPUや効率的なCPU推論ではよくある範囲です。
- プロンプト処理: ばらつきあり。 ここが最大のボトルネックです。あるプロンプトはキャッシュヒットにより素早く処理されますが、別のプロンプトは完全な再評価を強いられるため、遅延のスパイクが大きくなります。
- メモリ使用量: 効率的だが増加中。 VRAM/RAMの使用量はコンテキスト長に応じてスケールしており(4プロンプトで最大約~723 MiB)、12GBの制限内に収まっています。
詳細な内訳
1. 生成速度(Eval Time)
これは、モデルが新しいテキストトークンを生成する速度です。
- パフォーマンス: 約93〜105トークン/秒。
- ログの根拠:
- Task 460:
104.58 tokens per second - Task 776:
102.35 tokens per second - タスク 2848:
101.73 tokens per second - タスク 3079:
94.12 tokens per second - タスク 4726:
93.38 tokens per second
- Task 460:
- 分析: これは一貫しており、安定しています。文脈が大きくなるにつれて速度がわずかに低下します(104 から 93 t/s)。これは、メモリ帯域への負荷が増え、注意計算のオーバーヘッドが文脈ウィンドウの充填に伴って増えるためで、予想される挙動です。これは健康的な傾きです。
2. プロンプト処理(プリフィル時間)
これは入力プロンプトを処理するのにかかる時間です。これはログ上で大きく変動します。
- シナリオ A: キャッシュヒット(高速)
- タスク 2848:
856.58 ms(2,098 トークン分、約 2,449 t/s)。 - 理由: ログには
restored context checkpoint(コンテキストのチェックポイントを復元)と表示されています。システムは再開するのに十分似た過去の状態を見つけ、完全な再処理を回避できました。 - 性能: 優秀です。
- タスク 2848:
- シナリオ B: キャッシュミス / フル再評価(遅い)
- タスク 460:
68.01 ms(27 トークン分)。(プロンプトが小さいため高速です。) - タスク 776:
1944.26 ms(5,783 トークン分、約 2,974 t/s)。 - タスク 3079:
17307.06 ms(38,012 トークン分、約 2,196 t/s)。 - タスク 4726:
1153.57 ms(1,652 トークン分、約 1,432 t/s)。 - 理由: ログには明示的に次のように書かれています:
forcing full prompt re-processing due to lack of cache data(キャッシュデータがないため、プロンプトを完全に再処理することを強制しています)。 - 分析:
- タスク 3079 が最も懸念されます。単語を1つ生成する前に、プロンプトを読み取るだけで17.3秒かかっています。これはおそらく、プロンプトが非常に長い(38k トークン)ことと、キャッシュミスが原因です。
- タスク 4726 は、コンテキストサイズがタスク 2848 と似ているにもかかわらず遅くなっています。おそらく完璧なキャッシュ一致が見つからなかったためです(
sim_best = 0.958は良い値ですが、プリフィルを丸ごとスキップするのには不十分だった可能性があります。また、チェックポイント復元にオーバーヘッドがかかった可能性もあります)。
- タスク 460:
3. コンテキスト管理 & キャッシュ
- キャッシュ機構:
n_ctx_slot = 262144(256k のコンテキストウィンドウ)とn_keep = 0を使用しています。 - チェックポイント: システムは積極的にチェックポイントを作成しています(
created context checkpoint X of 50)。- 各チェックポイントは約 62.8 MiB です。
- タスク 3079 は処理中に 6 つのチェックポイントを作成しました。
- 問題として特定された点: ログの
forcing full prompt re-processing(プロンプトを完全に再処理することを強制)が、非常に異なるコンテキスト長に切り替えるときや、類似性の閾値が満たされないときに頻繁に発生しているようです。- タスク 776(5,783 トークン)では、前のスロットから
n_past = 23がありました。チェックポイントを確認しましたが、それらを使えず、結果として完全な再処理が強制されました。これは、前のコンテキスト(タスク 460、27 トークン分)が、タスク 776 にとって役に立つほど十分に異なっていたことを示唆します。 - タスク 3079(38,012 トークン)も、以前のチェックポイントを使えませんでした。おそらく、前のコンテキスト(タスク 2848、約 7.8k トークン)が十分に似ていなかったか、KV キャッシュに対する位置オフセットがうまく揃わなかったためです。
- タスク 776(5,783 トークン)では、前のスロットから
4. リソース利用
- メモリ:
- 4つのアクティブなプロンプトで、総状態サイズが723.154 MiBに到達しました。
- 上限は 12,000 MiB です。
- 状況: メモリ使用量は非常に低いです。余裕が十分あります。
- レイテンシ:
- 総応答時間は3秒(短いプロンプト)から34.5秒(長いプロンプトのプリフィル+生成)まで変動します。
- 34.5秒の遅延はすべて、38k トークン入力のプロンプト処理によるものです。
改善のための提案
- コンテキストウィンドウの使用を最適化:
- もし非常に長いプロンプト(例: 38k トークンのもの)を送っているなら、それを切り詰めるか要約できないか検討してください。38k トークンの処理には約17秒かかります。
- こうした長いプロンプトが頻繁にある場合は、すでに行っていなければ
--ctx-sizeの増加も検討してください。ただし、より重要なのは、類似した問い合わせでは同じコンテキストスロットを再利用してキャッシュヒットを最大化することです。
--cache-reuseを調整(該当する場合):- ログには
sim_bestの値が表示されています。多くの「プロンプトを完全に再処理」が発生しているなら、llama.cppのバージョンがそれらの微調整をサポートしている場合に、類似性の閾値やキャッシュ再利用の設定を変更してみることができます。ただし、デフォルトの挙動は通常堅牢です。
- ログには
- 「スロット」再利用を監視:
- 現状では、すべてのタスクに
id 0を使用しています(slot get_availabl: id 0)。これはキャッシュの観点では良いです(1つの長いコンテキストを生かし続けるため)。しかし、リクエストが重なる場合は処理が逐次になります。多数の同時ユーザーがいるなら、並行性を高めるために複数スロットの有効化(--parallelなど、環境に応じた設定)を検討してください。ただし、これはメモリ使用量の増加につながります。
- 現状では、すべてのタスクに
- 38k トークンのプロンプトを調査:
- タスク 3079 が外れ値です。なぜプロンプトが 38k トークンもあるのでしょうか?
- これがチャット履歴の場合は、LLM に送る前にアプリケーション層で「コンテキスト圧縮」戦略(古いメッセージの要約など)を実装することを検討してください。
- これが RAG(Retrieval Augmented Generation)の場合は、必要以上のチャンクを取得していないことを確認してください。
- タスク 3079 が外れ値です。なぜプロンプトが 38k トークンもあるのでしょうか?
結論
あなたの llama.cpp のセットアップは正常に動作しています。生成速度は安定しています(約 95-105 t/s)。主な「性能低下」はプロンプト処理によって引き起こされる可変レイテンシで、とくにキャッシュミスが発生して完全な再評価を強制されるような長いコンテキストで顕著です。これはアルゴリズム/利用パターンの問題であり、ハードウェアのボトルネックではありません。
エラーやクラッシュは検出されませんでした。 システムは安定しています。
[link] [comments]




