65 lines
2.1 KiB
Go
65 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/kami/maven/internal/router"
|
|
"github.com/kami/maven/internal/router/semantic"
|
|
)
|
|
|
|
// headsMain runs the deployed cascade minus the resident LLM: stage-0
|
|
// grammars → routing heads (fine-tuned e5 copy + softmax, router_heads.onnx,
|
|
// 0.6 decline threshold) → ONNX-embedder nearest-centroid classifier →
|
|
// 0.55 confidence gate. This is what a production turn takes when the model
|
|
// server is out (docs/routing.md: pickLLMRouter degrades to the classifier).
|
|
//
|
|
// The classifier is seeded from models/seeds like the daemon's seedClassifier,
|
|
// embedded with the real multilingual-e5-small model rather than the block
|
|
// hash, so this is the closest headless reproduction of the authoritative
|
|
// router output the slice-22 report can run.
|
|
//
|
|
// Requires the ONNX model files and a libonnxruntime.so. Pass the library via
|
|
// the MAVEN_ONNX_LIB environment variable, exactly as the daemon does.
|
|
func headsMain(poolPath, outPath string) {
|
|
lib := os.Getenv("MAVEN_ONNX_LIB")
|
|
if lib == "" {
|
|
fmt.Fprintln(os.Stderr, "heads mode needs MAVEN_ONNX_LIB pointing at libonnxruntime.so")
|
|
os.Exit(2)
|
|
}
|
|
const (
|
|
embedModel = "models/embedder/multilingual-e5-small/model_quantized.onnx"
|
|
tokPath = "models/embedder/multilingual-e5-small/tokenizer.json"
|
|
headsModel = "models/embedder/router-heads/router_heads.onnx"
|
|
)
|
|
emb, err := router.NewONNXEmbedder(embedModel, tokPath, lib)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "heads: embedder: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
defer emb.Close()
|
|
|
|
cls := router.NewClassifier(emb)
|
|
seedClassifier(cls)
|
|
|
|
heads, err := router.NewRouterHeads(headsModel, tokPath)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "heads: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
defer heads.Close()
|
|
|
|
acts := router.DefaultActMatcher{Fns: semantic.ExperimentActVerbs()}
|
|
r := router.New(router.Config{
|
|
Grammars: router.StageZeroGrammars(acts),
|
|
Classifier: cls,
|
|
Extractor: router.Extractor{
|
|
Time: router.StubDateTimeParser{},
|
|
Acts: acts,
|
|
Facts: router.DefaultFactParser{},
|
|
},
|
|
Threshold: 0.55,
|
|
Heads: heads,
|
|
})
|
|
runOverPool(r, poolPath, outPath)
|
|
} |