Files
llmgw/internal/cli/simengine.go
T
ilkerandClaude Opus 5 e07bc46c57
CI / test (push) Has been cancelled
Faz 0: iskelet ve sim-engine
Plan v0.2'nin Faz 0 çıktısı. Yazılan sıraya göre:

- cobra tabanlı CLI iskeleti; server/agent/ctl komutları henüz stub.
- internal/sim: OpenAI uyumlu sahte inference engine. Router'ı GPU olmadan
  gerçekçi koşullarda test edebilmek için gerçek bir engine'in router
  açısından önemli davranışlarını modeller:
    * continuous batching ve KV blok muhasebesi (head-of-line blocking dahil)
    * zincirlenmiş blok hash'leri + LRU ile otomatik prefix cache
    * batch büyüdükçe artan token gecikmesi
    * istemci koptuğunda isteğin düşürülüp blokların bırakılması
    * vLLM metrik adlarıyla /metrics (plan §7.6 engine kontratı)
- Testler: prefix hash zincirlemesi, LRU tahliyesi, iptal propagasyonu,
  kuyruklama, SSE formatı, usage/cached_tokens, metriklerin gerçek
  Prometheus parser'ıyla okunabilirliği.
- Gitea Actions CI: gofmt, vet, race detector.

Modül yolu gitea.mynodes.xyz/ilker/llmgw; `make rename` ile değiştirilebilir.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 01:00:03 +02:00

88 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package cli
import (
"context"
"errors"
"net"
"net/http"
"os/signal"
"syscall"
"time"
"github.com/spf13/cobra"
"gitea.mynodes.xyz/ilker/llmgw/internal/sim"
)
func newSimEngineCmd() *cobra.Command {
cfg := sim.Default()
var listen string
cmd := &cobra.Command{
Use: "sim-engine",
Short: "OpenAI uyumlu sahte inference engine (test için)",
Long: "Gerçek bir engine'in router açısından önemli davranışlarını simüle eder:\n" +
"continuous batching, KV blok muhasebesi, prefix cache, vLLM formatında /metrics.\n" +
"Router'ı GPU olmadan test etmek için kullanılır.",
RunE: func(cmd *cobra.Command, _ []string) error {
log := logger()
eng := sim.New(cfg)
defer eng.Close()
srv := &http.Server{
Addr: listen,
Handler: sim.NewServer(eng, log),
ReadHeaderTimeout: 10 * time.Second,
}
ln, err := net.Listen("tcp", listen)
if err != nil {
return err
}
log.Info("sim-engine dinliyor",
"addr", ln.Addr().String(),
"model", cfg.Model,
"max_num_seqs", cfg.MaxNumSeqs,
"num_gpu_blocks", cfg.NumGPUBlocks,
"prefix_cache_blocks", cfg.PrefixCacheBlocks,
)
ctx, stop := signal.NotifyContext(cmd.Context(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
errCh := make(chan error, 1)
go func() { errCh <- srv.Serve(ln) }()
select {
case err := <-errCh:
if errors.Is(err, http.ErrServerClosed) {
return nil
}
return err
case <-ctx.Done():
log.Info("kapanıyor")
shutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
return srv.Shutdown(shutCtx)
}
},
}
f := cmd.Flags()
f.StringVar(&listen, "listen", ":8000", "dinlenecek adres")
f.StringVar(&cfg.Model, "model", cfg.Model, "sunulan model adı")
f.IntVar(&cfg.MaxNumSeqs, "max-num-seqs", cfg.MaxNumSeqs, "eşzamanlı dizi sayısı (batch kapasitesi)")
f.IntVar(&cfg.BlockSize, "block-size", cfg.BlockSize, "KV blok başına token")
f.IntVar(&cfg.NumGPUBlocks, "num-gpu-blocks", cfg.NumGPUBlocks, "toplam KV cache bloğu")
f.IntVar(&cfg.PrefixCacheBlocks, "prefix-cache-blocks", cfg.PrefixCacheBlocks, "prefix cache blok kapasitesi (0=kapalı)")
f.Float64Var(&cfg.PrefillTokensPerSec, "prefill-tps", cfg.PrefillTokensPerSec, "prefill hızı (token/sn, engine geneli)")
f.Float64Var(&cfg.DecodeTokensPerSec, "decode-tps", cfg.DecodeTokensPerSec, "tek dizi decode hızı (token/sn)")
f.Float64Var(&cfg.BatchContention, "batch-contention", cfg.BatchContention, "batch'teki her ek dizinin yavaşlatma katsayısı")
f.IntVar(&cfg.DefaultOutputTokens, "default-output-tokens", cfg.DefaultOutputTokens, "max_tokens verilmezse üretilecek token")
f.DurationVar(&cfg.Tick, "tick", cfg.Tick, "simülasyon adımı")
f.Float64Var(&cfg.FailRate, "fail-rate", 0, "isteklerin yapay hata oranı (kaos testi)")
f.Int64Var(&cfg.Seed, "seed", 0, "rastgelelik tohumu (0=zaman)")
return cmd
}