What happens
When a model is installed from the gallery, LocalAI writes the recommended sampling parameters into the model YAML as top level keys:
name: qwen3.5-122b-a10b
min_p: 0
presence_penalty: 1.5
repeat_penalty: 1
temperature: 0.7
top_k: 20
top_p: 0.8
parameters:
model: llama-cpp/models/Qwen3.5-122B-A10B-Q4_K_M-00001-of-00003.gguf
The config loader does not read them there. It expects them inside parameters:. Every one of those lines is inert.
Write side, six fields copied to top level keys:
|
// Merge inference defaults into configMap so they are persisted without losing unknown fields. |
|
if modelConfig.Temperature != nil { |
|
if _, exists := configMap["temperature"]; !exists { |
|
configMap["temperature"] = *modelConfig.Temperature |
|
} |
|
} |
|
if modelConfig.TopP != nil { |
|
if _, exists := configMap["top_p"]; !exists { |
|
configMap["top_p"] = *modelConfig.TopP |
|
} |
|
} |
|
if modelConfig.TopK != nil { |
|
if _, exists := configMap["top_k"]; !exists { |
|
configMap["top_k"] = *modelConfig.TopK |
|
} |
|
} |
|
if modelConfig.MinP != nil { |
|
if _, exists := configMap["min_p"]; !exists { |
|
configMap["min_p"] = *modelConfig.MinP |
|
} |
|
} |
|
if modelConfig.RepeatPenalty != 0 { |
|
if _, exists := configMap["repeat_penalty"]; !exists { |
|
configMap["repeat_penalty"] = modelConfig.RepeatPenalty |
|
} |
|
} |
|
if modelConfig.PresencePenalty != 0 { |
|
if _, exists := configMap["presence_penalty"]; !exists { |
|
configMap["presence_penalty"] = modelConfig.PresencePenalty |
|
} |
|
} |
Read side, the struct that holds those fields is nested under parameters:
|
schema.PredictionOptions `yaml:"parameters,omitempty" json:"parameters,omitempty"` |
So LocalAI writes a file it cannot read back.
Why it is easy to miss
The same defaults are applied again when the model loads:
|
ApplyInferenceDefaults(cfg, cfg.Name, cfg.Model) |
That second pass fills in any value that is still unset, from the same table the install used. The numbers come out correct either way, so nothing looks broken. /api/models/config-json/<model> also shows them correctly nested, because it reports the loaded config rather than the file on disk.
When it actually causes a problem
- Editing one of those top level values to override a default does nothing, and nothing warns you.
- If a model family is missing from
inference_defaults.json, the values are written at install and then lost on every load, with nothing to restore them.
How we ran into it
A 122B model would not load. We wanted to pin the batch size, so we added batch: 512 at the top level of the model YAML, matching where the sampling parameters already sat in that same file. It had no effect, and the log kept reporting the auto tuned value instead. Moving it under parameters: fixed it straight away.
That is when we noticed the sampling parameters above it were sitting in the same dead position, and that we had not put them there ourselves. The gallery install had written them.
Suggested fix
Write the defaults into the nested parameters map instead of as top level keys, so they land where the loader reads them.
Version
Seen on v4.7.1 (localai/localai:latest-gpu-vulkan). Code links point at master (aaec1d6), where the same code is present.
What happens
When a model is installed from the gallery, LocalAI writes the recommended sampling parameters into the model YAML as top level keys:
The config loader does not read them there. It expects them inside
parameters:. Every one of those lines is inert.Write side, six fields copied to top level keys:
LocalAI/core/gallery/models.go
Lines 624 to 654 in aaec1d6
Read side, the struct that holds those fields is nested under
parameters:LocalAI/core/config/model_config.go
Line 44 in aaec1d6
So LocalAI writes a file it cannot read back.
Why it is easy to miss
The same defaults are applied again when the model loads:
LocalAI/core/config/model_config.go
Line 1363 in aaec1d6
That second pass fills in any value that is still unset, from the same table the install used. The numbers come out correct either way, so nothing looks broken.
/api/models/config-json/<model>also shows them correctly nested, because it reports the loaded config rather than the file on disk.When it actually causes a problem
inference_defaults.json, the values are written at install and then lost on every load, with nothing to restore them.How we ran into it
A 122B model would not load. We wanted to pin the batch size, so we added
batch: 512at the top level of the model YAML, matching where the sampling parameters already sat in that same file. It had no effect, and the log kept reporting the auto tuned value instead. Moving it underparameters:fixed it straight away.That is when we noticed the sampling parameters above it were sitting in the same dead position, and that we had not put them there ourselves. The gallery install had written them.
Suggested fix
Write the defaults into the nested
parametersmap instead of as top level keys, so they land where the loader reads them.Version
Seen on v4.7.1 (
localai/localai:latest-gpu-vulkan). Code links point at master (aaec1d6), where the same code is present.