Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
87 lines
2.9 KiB
Go
87 lines
2.9 KiB
Go
package engines
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
// SimConfig locates the simulated engine.
|
|
type SimConfig struct {
|
|
// Bin is the llmgw binary itself; the engine is one of its subcommands.
|
|
// Empty means whatever started this agent, which is right almost always.
|
|
Bin string `koanf:"bin"`
|
|
}
|
|
|
|
// Sim launches llmgw's own simulated engine.
|
|
//
|
|
// It is in the production registry on purpose. A cluster can be brought up and
|
|
// exercised end to end — placement, fabrics, multi-node sequencing, failure and
|
|
// rebuild — on machines that have no GPUs, which is the only way most of that
|
|
// path gets tested at all. The multi-node launch sequence went four phases
|
|
// without ever running, because the only things exercising it were stub
|
|
// processes that exercised the command line and nothing else.
|
|
//
|
|
// Nothing about it pretends to be real: the model name it serves is whatever it
|
|
// is told, the tokens are invented, and it says so in its own logs.
|
|
type Sim struct{ cfg SimConfig }
|
|
|
|
// Name identifies the engine in the catalog.
|
|
func (*Sim) Name() string { return "sim" }
|
|
|
|
// HealthPath is the simulated engine's readiness endpoint.
|
|
func (*Sim) HealthPath() string { return "/health" }
|
|
|
|
// MetricsPath is its Prometheus endpoint, in vLLM's vocabulary.
|
|
func (*Sim) MetricsPath() string { return "/metrics" }
|
|
|
|
// ServesHTTP reports whether this rank answers the API.
|
|
//
|
|
// Only the leader, exactly as vLLM and SGLang behave — which is the behaviour
|
|
// this engine exists to let us test.
|
|
func (*Sim) ServesHTTP(s ShardSpec) bool { return s.Leader() }
|
|
|
|
// Validate accepts anything the arithmetic allows.
|
|
//
|
|
// No compute-capability checks and no quantization rules: there is no hardware
|
|
// to be wrong about, and inventing refusals would make this a worse stand-in
|
|
// for the engines it stands in for.
|
|
func (*Sim) Validate(p Profile, gpus []GPUInfo) error {
|
|
return validateCommon(p, gpus)
|
|
}
|
|
|
|
// Commands returns the single process that makes up one shard.
|
|
func (s *Sim) Commands(spec ShardSpec) ([]Command, error) {
|
|
bin := s.cfg.Bin
|
|
if bin == "" {
|
|
exe, err := os.Executable()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("locating the llmgw binary for the sim engine: %w", err)
|
|
}
|
|
bin = exe
|
|
}
|
|
p := spec.Profile
|
|
|
|
args := []string{"sim-engine",
|
|
"--listen", net.JoinHostPort(spec.Host(), strconv.Itoa(spec.HTTPPort)),
|
|
"--model", p.ServedModelName,
|
|
}
|
|
if spec.NNodes > 1 {
|
|
args = append(args,
|
|
"--nnodes", strconv.Itoa(spec.NNodes),
|
|
"--node-rank", strconv.Itoa(spec.Rank),
|
|
"--dist-init-addr", spec.LeaderAddr+":"+strconv.Itoa(spec.LeaderPort),
|
|
)
|
|
}
|
|
args = append(args, p.Args...)
|
|
|
|
return []Command{{
|
|
Name: "sim-engine", Path: bin, Args: args,
|
|
Env: materializeEnv(baseEnv(spec)),
|
|
// Workers dial the leader, so the leader has to be listening first.
|
|
// Both ranks express the same wait because both know the same address.
|
|
WaitForLeaderPort: spec.NNodes > 1 && !spec.Leader(),
|
|
}}, nil
|
|
}
|