CI / test (push) Has been cancelled
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>
88 lines
2.9 KiB
Go
88 lines
2.9 KiB
Go
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
|
||
}
|