• GitHub - soukouki/loopguard: A llama-server proxy that detects loops during output and interrupts processing · GitHub
  • loopguard は、llama-swapllama-server の間に配置する軽量なストリーミングプロキシであり、LLMの出力ループ(同じ文字列の繰り返し)を検知して、ストリームを早期に打ち切るためのツールです。
  • モチベ
    • Gemma 4 12BとかTernary Bonsai 27Bとか動かしてると、たまに推論がループして困っていた
      • 手動での介入をしない場合、コンテキスト長のエラーが起きるまで待つしかなかった。
      • llama-serverにはDRYなどのループを減らすオプションがあるが、使ったところでループの代わりに幾つかのトークンが不規則に出力されるという微妙な結果にしかならなかった。
        • むしろn-gram投機的デコードの効果が失われて、コンテキスト長を埋めるまでの時間が伸びるだけ
    • llama-swapllama-serverの間に入ってAPIをプロキシして、推論がループしていたらそこで出力を打ち切ればよいのでは、と考えた。
  • 仕様書はClaude Sonnet 5くんが、実装はLaguna S 2.1くんがやってくれた
    • Laguna S 2.1くん強くない?
    • ローカルLLMでこのレベルの作業が出来る時代が来たんだ

実際に動作した際のログの様子

0.13.643.844 I slot print_timing: id  3 | task 0 | prompt processing, n_tokens =  12190, progress = 1.00, t =  10.57 s / 1153.75 tokens per second
0.16.683.330 I slot print_timing: id  3 | task 0 | n_decoded =    336, tg = 111.93 t/s, tg_3s = 111.93 t/s
0.19.690.380 I slot print_timing: id  3 | task 0 | n_decoded =    674, tg = 112.17 t/s, tg_3s = 112.40 t/s
0.22.698.781 I slot print_timing: id  3 | task 0 | n_decoded =   1025, tg = 113.67 t/s, tg_3s = 116.67 t/s
0.25.702.727 I slot print_timing: id  3 | task 0 | n_decoded =   1363, tg = 113.38 t/s, tg_3s = 112.52 t/s
0.28.710.368 I slot print_timing: id  3 | task 0 | n_decoded =   1692, tg = 112.58 t/s, tg_3s = 109.39 t/s
0.31.716.927 I slot print_timing: id  3 | task 0 | n_decoded =   2044, tg = 113.33 t/s, tg_3s = 117.08 t/s
0.34.718.707 I slot print_timing: id  3 | task 0 | n_decoded =   2384, tg = 113.32 t/s, tg_3s = 113.27 t/s
0.37.725.899 I slot print_timing: id  3 | task 0 | n_decoded =   2728, tg = 113.46 t/s, tg_3s = 114.39 t/s
0.40.728.519 I slot print_timing: id  3 | task 0 | n_decoded =   3070, tg = 113.51 t/s, tg_3s = 113.90 t/s
0.43.735.549 I slot print_timing: id  3 | task 0 | n_decoded =   3420, tg = 113.80 t/s, tg_3s = 116.39 t/s
0.46.737.185 I slot print_timing: id  3 | task 0 | n_decoded =   3786, tg = 114.53 t/s, tg_3s = 121.93 t/s
0.49.750.315 I slot print_timing: id  3 | task 0 | n_decoded =   4571, tg = 126.73 t/s, tg_3s = 260.53 t/s
↑ここでtg_3sの値が跳ね上がっている。n-gram投機的デコードのオプションを有効にしているので、繰り返しに入って投機的デコードの成功率が上がったことによる影響と思われる
2026/07/27 20:23:05 loopguard: loop detected, terminating stream
↑ループを検知してストリームを停止している
0.50.770.261 W srv          stop: cancel task, id_task = 0
0.50.799.464 I slot      release: id  3 | task 0 | stop processing: n_tokens = 17349, truncated = 0