mirror of
https://github.com/unslothai/unsloth.git
synced 2026-08-25 16:52:26 +00:00
Tighten the comments added for PR #8757
This commit is contained in:
parent
afe7c9cec3
commit
f04ad2fdb9
4 changed files with 17 additions and 34 deletions
|
|
@ -127,14 +127,9 @@ export function getReplayedParams(
|
|||
if (!remembered) {
|
||||
return current;
|
||||
}
|
||||
// Key by key over the remembered set, not a spread of the entry. An entry is
|
||||
// whatever is in the settings row, and this app is not its only possible
|
||||
// writer: the backend's ChatInferenceSettings accepts every persisted key
|
||||
// inside a per-model dict, maxSeqLength included, and the client sanitiser
|
||||
// keeps them. Spreading such an entry would replay a context the backend
|
||||
// never loaded -- the exact thing REMEMBERED_INFERENCE_PARAM_KEYS exists to
|
||||
// prevent on the way in -- and would carry any stale key straight into the
|
||||
// live params.
|
||||
// Key by key, not a spread: the row accepts every persisted key (maxSeqLength
|
||||
// included) from any writer, and spreading one would replay a context the
|
||||
// backend never loaded, plus any stale key, into the live params.
|
||||
const replayed = { ...current };
|
||||
for (const key of REMEMBERED_INFERENCE_PARAM_KEYS) {
|
||||
const value = remembered[key];
|
||||
|
|
|
|||
|
|
@ -2215,10 +2215,8 @@ function getHydratedSettingsState(
|
|||
) {
|
||||
// Same fence as the global set above: a key the user moved while this
|
||||
// request was in flight is their edit, and the memory does not outrank it.
|
||||
// REMEMBERED, not PERSISTED: the same distinction getReplayedParams draws.
|
||||
// maxSeqLength is persisted but never remembered, and an entry that carries
|
||||
// one anyway -- the row accepts it -- must not replace the context the model
|
||||
// actually loaded with.
|
||||
// REMEMBERED, not PERSISTED, as in getReplayedParams: a maxSeqLength the row
|
||||
// happens to carry must not replace the context the model loaded with.
|
||||
const replayed = { ...params };
|
||||
for (const key of REMEMBERED_INFERENCE_PARAM_KEYS) {
|
||||
const value = remembered[key];
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
||||
|
||||
// The hydration replay is a second, independent copy of the replay rules, so it
|
||||
// needs its own guard for the one key the memory deliberately does not keep.
|
||||
// The hydration replay is a second copy of the replay rules, so it needs its own
|
||||
// guard. Its own file: per-model-params-hydration.test.ts shares store state
|
||||
// across its tests, and an appended case picks up an earlier one's temperature.
|
||||
|
||||
import assert from "node:assert/strict";
|
||||
import { register } from "node:module";
|
||||
|
|
@ -22,12 +23,8 @@ const { useChatRuntimeStore } = await import(
|
|||
const QWEN = "unsloth/Qwen3.5-9B-GGUF";
|
||||
|
||||
test("hydration does not replay a maxSeqLength an entry happens to carry", async () => {
|
||||
// maxSeqLength is persisted but never remembered: the context a model loads
|
||||
// with is owned by its load config, and replaying a second copy would leave
|
||||
// the runtime advertising a context the backend never loaded. This app never
|
||||
// writes one into an entry -- but the settings row accepts one, from an older
|
||||
// client, a hand-written payload or a future key set, so the read side has to
|
||||
// hold the rule too, not just the write side.
|
||||
// maxSeqLength is persisted but never remembered: the context belongs to the
|
||||
// load config. This app writes none into an entry, but the row accepts one.
|
||||
settingsHttp.settings = {
|
||||
inferenceParamsByModel: {
|
||||
[QWEN]: { temperature: 0.2, maxSeqLength: 131072 },
|
||||
|
|
|
|||
|
|
@ -362,10 +362,8 @@ test("the snapshot drops params the current model never set", () => {
|
|||
assert.equal("topK" in picked, false);
|
||||
});
|
||||
|
||||
// An entry is whatever the settings row holds, and this app is not its only
|
||||
// possible writer: the backend's ChatInferenceSettings accepts every persisted
|
||||
// key inside a per-model dict, so the read side has to hold the same rules the
|
||||
// write side does rather than trusting the shape.
|
||||
// The row accepts every persisted key from any writer, so the read side has to
|
||||
// hold the write side's rules rather than trust the entry's shape.
|
||||
test("a maxSeqLength in a stored entry is not replayed over the loaded context", () => {
|
||||
const replayed = getReplayedParams(
|
||||
true,
|
||||
|
|
@ -375,8 +373,7 @@ test("a maxSeqLength in a stored entry is not replayed over the loaded context",
|
|||
true,
|
||||
);
|
||||
assert.equal(replayed.temperature, 0.2, "the remembered value still replays");
|
||||
// The same rule pickRememberedParams follows on the way in: a second copy of
|
||||
// the context would leave the runtime advertising one the backend never loaded.
|
||||
// A second copy of the context would advertise one the backend never loaded.
|
||||
assert.equal(replayed.maxSeqLength, 4096);
|
||||
});
|
||||
|
||||
|
|
@ -389,17 +386,13 @@ test("a key that is not an inference param cannot reach the live params", () =>
|
|||
true,
|
||||
);
|
||||
assert.equal(replayed.temperature, 0.2);
|
||||
// params flows on into request bodies and into the settings write, where the
|
||||
// payload is extra="forbid".
|
||||
// params flows on into request bodies and into an extra="forbid" settings write.
|
||||
assert.equal("notAParam" in replayed, false);
|
||||
});
|
||||
|
||||
// Model ids are not sanitised identifiers. A Hub repo is slash-separated, a
|
||||
// custom folder is an absolute path -- a drive path on Windows, a UNC path from
|
||||
// a share or WSL, a spaced path under ~/Library on macOS -- and an external
|
||||
// model is provider-qualified. All of them are opaque keys here, and an id that
|
||||
// did not survive the round trip would mean that platform silently cannot
|
||||
// remember settings at all.
|
||||
// Model ids are opaque keys: a Hub repo, an absolute path on any OS, or a
|
||||
// provider-qualified external id. One that did not round trip would mean that
|
||||
// platform silently cannot remember settings.
|
||||
for (const [label, id] of [
|
||||
["a Windows drive path", "C:\\Users\\Daniel\\models\\Qwen3-8B"],
|
||||
["a UNC share path", "\\\\fileserver\\models\\gemma-3-270m-it"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue