IQuest-Coder Loop-Instructとaiderの生成速度
IQuest-Coder-V1-40B-Loop-Instructはaiderで0.6〜8 tok/sでした。AIコーディング環境の構築に向け、whole edit、文脈の量、生成設定を分けて考え、別のnvfp4構成と比較します。
入力処理は速く、生成は遅い
IQuest-Coder-V1-40B-Loop-Instruct を aider で使うと、入力の処理は速い一方、生成は 0.6〜8 tok/s でした。編集を繰り返す用途では、出力を待つ時間が長くなります。
同時期の別の構成では、IQuest-Coder-V1-40B-Instruct-nvfp4 が 25〜28 tok/s を出していました。同じ 40B クラスでも結果が異なるため、編集形式や設定を分けて考えます。
編集形式と待ち時間
aider では、修正を確認して次の指示を出す作業を繰り返します。1 回の待ち時間が長いと、そのたびに作業が止まります。
当時のメモでは、次のように評価していました。
Prefill は十分速いが、decode が致命的に遅い。
vLLM の速度とキャッシュ使用量
- Prefill(入力処理)は数百〜
900 tok/sでした。 - Decode(生成)は
0.6〜8 tok/sでした。 - GPU や KV cache の不足を主因とは見ていません。
aiderで編集を繰り返すには、生成の待ち時間が長い状態でした。
vLLM のログにも、生成速度の低さが出ています。
(APIServer pid=1) INFO 01-09 19:15:06 [loggers.py:257] Engine 000: Avg prompt throughput: 0.0 tokens/s, Avg generation throughput: 8.0 tokens/s, Running: 1 reqs, Waiting: 0 reqs, GPU KV cache usage: 12.2%, Prefix cache hit rate: 6.3%
(APIServer pid=1) INFO 01-09 19:15:16 [loggers.py:257] Engine 000: Avg prompt throughput: 0.0 tokens/s, Avg generation throughput: 8.0 tokens/s, Running: 1 reqs, Waiting: 0 reqs, GPU KV cache usage: 12.5%, Prefix cache hit rate: 6.3%
(APIServer pid=1) INFO 01-09 19:16:16 [loggers.py:257] Engine 000: Avg prompt throughput: 251.4 tokens/s, Avg generation throughput: 4.0 tokens/s, Running: 1 reqs, Waiting: 0 reqs, GPU KV cache usage: 7.0%, Prefix cache hit rate: 6.4%
(APIServer pid=1) INFO 01-09 19:17:06 [loggers.py:257] Engine 000: Avg prompt throughput: 73.4 tokens/s, Avg generation throughput: 1.1 tokens/s, Running: 0 reqs, Waiting: 0 reqs, GPU KV cache usage: 0.0%, Prefix cache hit rate: 6.8%
KV cache usage は 7.0%〜13.8% で、キャッシュを使い切ってはいませんでした。Prefix cache hit rate は 6.3%〜6.8% です。この値だけでは速度差を説明できず、生成側を調べる必要があります。
遅さに関係する条件
メモでは、次の 4 つを原因の候補として挙げていました。
1. 40B モデルで whole edit を返す
whole edit はファイル全体を返すため、小さな修正でも生成するトークン数が増えます。生成速度が低いと、その分だけ待ち時間が長くなります。
このとき返された Django モデルの一部です。
from django.db import models
from django.utils.translation import gettext_lazy as _
from core.models import TimeStampedModel, SoftDeleteModel
class Comment(TimeStampedModel, SoftDeleteModel):
class Status(models.TextChoices):
PENDING = 'pending', _('Pending')
APPROVED = 'approved', _('Approved')
SPAM = 'spam', _('Spam')
TRASH = 'trash', _('Trash')
site = models.ForeignKey('core.Site', on_delete=models.CASCADE)
post = models.ForeignKey('content.Post', on_delete=models.CASCADE)
parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True)
author_user = models.ForeignKey('auth.User', on_delete=models.SET_NULL, null=True, blank=True)
author_name = models.CharField(max_length=255)
author_email = models.EmailField()
author_url = models.URLField(blank=True)
body = models.TextField()
status = models.CharField(max_length=20, choices=Status.choices, default=Status.PENDING)
ip_hash = models.CharField(max_length=64)
user_agent = models.TextField(blank=True)
class Meta:
indexes = [
models.Index(fields=['post', 'status', 'created_at']),
]
def __str__(self):
return f"Comment by {self.author_name} on {self.post}"
def approve(self):
self.status = self.Status.APPROVED
self.save(update_fields=['status'])
def mark_as_spam(self):
self.status = self.Status.SPAM
self.save(update_fields=['status'])
def move_to_trash(self):
self.status = self.Status.TRASH
self.save(update_fields=['status'])
def restore(self):
self.status = self.Status.PENDING
self.save(update_fields=['status'])
def is_approved(self):
return self.status == self.Status.APPROVED
まとまったコードは返せています。ただし、生成速度が 1 桁 tok/s では、この長さの出力を毎回待つことになります。
2. 文脈が大きい
repo-map と複数ファイルを渡すと、モデルが参照する情報が増えます。メモでは、repo-map や /add 対象を減らす案を挙げていました。
文脈が大きいと説明や差分も長くなりやすく、生成の遅さが目立ちます。
3. サンプリングを使っている
生成設定の変更案は、temperature=0 にして greedy decoding を使うことです。毎回、確率が最も高いトークンを選ぶ方法です。コード編集では、返答の再現性と早く出力を終えることを優先する案です。
4. 40B クラスの単発生成
40B クラスは、1 リクエストずつの生成に向かない可能性もあります。ただし、別の nvfp4 構成では 25〜28 tok/s が出ています。モデルの大きさだけでなく、編集形式、文脈、生成設定をあわせて見る必要があります。
メモに挙げた変更案
変更案は次の順番でした。
whole editをやめてdiff/patch形式にするtemperature=0で回すrepo-mapや/add対象を減らすmax_model_lenを必要最小にする- 必要なら、量子化版や軽いコード特化モデル(20B〜32B)に変更する
最初の 1 と 2 は、出力を短くし、生成時の選択を単純にする案です。入力処理より、生成にかかる時間を減らすことを優先しています。
別の nvfp4 構成の結果
Firworks-IQuest-Coder-V1-40B-Instruct-nvfp4.md には、次の値が記録されていました。
- Prompt throughput:
1100〜2300 tok/s - Generation throughput:
25〜28 tok/s - KV cache usage:
2〜12% - Prefix cache hit rate:
20〜45%
25〜28 tok/s なら、200 tokens の出力は数秒台です。今回の 0.6〜8 tok/s では、同じ長さでも待ち時間が大きく変わります。
この比較は、同じ条件で測ったモデル順位ではありません。aider での使いやすさは、出力形式、文脈の量、生成設定にも左右されます。
今回の結果
今回の 40B + whole edit では、低い生成速度 (t/s) と長い出力が重なりました。入力処理の速さだけでは、編集の待ち時間は決まりません。
