Ctrl K
ComunidadGuías…

internal/autogen/densectxceiling_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package autogen

import (
	"os"
	"path/filepath"
	"testing"
)

// A dense model trained past 128k must be sized to its own ceiling when the KV
// cache for that window fits the budget. The default ladder used to top out at
// 131072, which pinned every 256k/512k/1M model there and left the VRAM those
// extra tokens would have used unallocated.
func TestGetDenseCtx_DefaultLadderReachesModelMax(t *testing.T) {
	var s Settings
	s.applyDefaults()

	// Roomy budget: ~0.6 GB of KV per 128k tokens, 40 GB target, 8 GB weights.
	p := DenseCtxParams{
		ModelMax: 262144, PerTokGB: 0.6 / 131072, KvConstGB: 0.1,
		FileSizeGB: 8, TargetVramGB: 40, Overhead: 1.5,
		Ladder: s.DenseCtxLadder, MinCtx: s.DenseMinCtx,
	}
	got := GetDenseCtx(p)
	if got.Ctx != 262144 {
		t.Errorf("ctx = %d (%s), want the model max 262144", got.Ctx, got.Note)
	}
	if got.Note != "model-max" {
		t.Errorf("note = %q, want %q", got.Note, "model-max")
	}
}

// An explicitly configured ladder is still a ceiling the sizer honors.
func TestGetDenseCtx_ExplicitLadderStillCaps(t *testing.T) {
	p := DenseCtxParams{
		ModelMax: 262144, PerTokGB: 0.6 / 131072, KvConstGB: 0.1,
		FileSizeGB: 8, TargetVramGB: 40, Overhead: 1.5,
		Ladder: []int{65536, 32768}, MinCtx: 32768,
	}
	if got := GetDenseCtx(p); got.Ctx != 65536 {
		t.Errorf("ctx = %d (%s), want the ladder top 65536", got.Ctx, got.Note)
	}
}

// No ladder at all is not a crash and not a 0-token window: the model's trained
// ceiling is the only cap left.
func TestGetDenseCtx_EmptyLadderUsesModelMax(t *testing.T) {
	p := DenseCtxParams{
		ModelMax: 262144, PerTokGB: 0.6 / 131072, KvConstGB: 0.1,
		FileSizeGB: 8, TargetVramGB: 40, Overhead: 1.5,
		MinCtx: 32768,
	}
	if got := GetDenseCtx(p); got.Ctx != 262144 {
		t.Errorf("ctx = %d (%s), want the model max 262144", got.Ctx, got.Note)
	}
}

// An install made before the ceiling moved has the old ladder written into its
// generate file AND its UI settings sidecar, so raising the default alone is
// invisible: both copies have to be migrated or the 128k cap survives forever.
func TestSettings_LegacyCtxLadderMigrates(t *testing.T) {
	s := Settings{DenseCtxLadder: []int{131072, 65536, 32768}}
	s.applyDefaults()
	if got := s.DenseCtxLadder[0]; got != 1048576 {
		t.Errorf("ladder top = %d, want the current default 1048576 (ladder=%v)", got, s.DenseCtxLadder)
	}

	// A ladder that is NOT the old shipped default is a deliberate cap: keep it.
	keep := Settings{DenseCtxLadder: []int{131072, 32768}}
	keep.applyDefaults()
	if len(keep.DenseCtxLadder) != 2 || keep.DenseCtxLadder[0] != 131072 {
		t.Errorf("hand-set ladder was rewritten: %v", keep.DenseCtxLadder)
	}
}

// The whole point, on a real file: gemma-4-12B-it-qat is trained to 262144 and
// was being loaded at 131072 with ~10 GB of a 22.8 GB budget unspent.
func TestEstimatePlan_Gemma4_12B_ReachesTrainedCeiling(t *testing.T) {
	if realModelsRoot == "" {
		t.Skip("no local model tree")
	}
	p := filepath.Join(realModelsRoot, "unsloth", "gemma-4-12B-it-qat-GGUF", "gemma-4-12B-it-qat-UD-Q4_K_XL.gguf")
	if _, err := os.Stat(p); err != nil {
		t.Skip("gemma-4-12B-it-qat not present")
	}
	meta, err := ReadGgufMetadata(p)
	if err != nil {
		t.Fatal(err)
	}
	if meta.ContextLength != 262144 {
		t.Skipf("this build of the model is trained to %d, not 262144", meta.ContextLength)
	}
	s := Settings{TargetVramGB: 22.8, VramOverheadGB: 0.5, MaxRamGB: 24}
	s.applyDefaults()
	est, err := EstimatePlan(s, meta, EstimateInput{})
	if err != nil {
		t.Fatal(err)
	}
	if est.Ctx != 262144 {
		t.Errorf("ctx = %d (%.2f GB est), want the trained 262144", est.Ctx, est.EstVramGB)
	}
}