Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/host/server/native-control.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ return {summary:result.summary??'Deleted',removed:result.plan?.gb??null};}
if(cfg.vision){if(cfg.vision_tokens!=null)cfg.vision={...cfg.vision,max_tokens:cfg.vision_tokens};if(cfg.vision_min_tokens!=null)cfg.vision={...cfg.vision,min_tokens:cfg.vision_min_tokens};}cfg.mcp={...(cfg.mcp??{}),...(cfg.mcp_timeout_s!=null?{timeout_s:cfg.mcp_timeout_s}:{}),...(cfg.mcp_max_rounds!=null?{max_rounds:cfg.mcp_max_rounds}:{}),...(cfg.mcp_max_result_chars!=null?{max_result_chars:cfg.mcp_max_result_chars}:{})};
/* The model's own choices win over what setup wrote into the arguments: "Draft layer (MTP)" off leaves --mtp out of every start, and a picture reading that is off leaves --vision out (setup writes both again whenever it runs; the saved settings are applied here, on every load). */
if((cfg.mtp===false||cfg.drafting==='off')&&Array.isArray(cfg.args))cfg.args=withoutDraftLayer(cfg.args);
if(!cfg.vision&&Array.isArray(cfg.args))cfg.args=cfg.args.filter(a=>a!=='--vision');
if(!cfg.vision&&Array.isArray(cfg.args))cfg.args=cfg.args.filter((a,i,list)=>a!=='--vision'||(i+1<list.length&&!list[i+1].startsWith('--')));
for(const arg of cfg.args??[])if(arg.endsWith('.gguf')&&!existsSync(resolve(repo(),arg)))throw new Error('An engine argument names a missing GGUF. Restore the saved arguments or repair the files.');
/* The app's own choice of request slots (4, fewer where the card has no room) is part of the configuration, so a tune measures the engine a load will start: slots take VRAM from the expert cache. */
const parallelChoice=packaged&&!ownEngine(config)?chooseParallel({config:cfg,values:args.values??{},hardware:snapshot.hardware?.gpus?.length?snapshot.hardware:{gpus:hardwareProbe()??[]}}):null;
Expand Down
15 changes: 15 additions & 0 deletions apps/host/tests/draft-layer.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,21 @@ test('picture reading off sticks: no vision section and no --vision on the engin
} finally { await f.native.close(); f.cleanup(); }
});

test('DeepSeek load keeps valued vision options and removes only the bare flag', async () => {
for (const vision of [['--vision', 'off'], ['--vision', 'on'], ['--vision']]) {
for (const tail of [[], ['--dspark', 'none']]) {
const base = ['--pack', '/p', '--eos', '1'];
const f = fixture({ arch: 'deepseek41', exe: 'strata-dsv41', args: [...base, ...vision, ...tail] });
try {
await f.native.refresh(true);
const job = await finish(f.native, f.native.operation('load', { model: 'q2_0' }).id);
assert.equal(job.state, 'done', job.error);
assert.deepEqual(f.saved[0].args, [...base, ...(vision.length===2?vision:[]), ...tail]);
} finally { await f.native.close(); f.cleanup(); }
}
}
});

test('picture reading on keeps --vision; the Models screen sees the prepared pictures instead of "off"', async () => {
const f = fixture({ vision: visionSection });
try {
Expand Down
19 changes: 19 additions & 0 deletions tests/terminal/test_launch_vision_value.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""DeepSeek's valued picture option stays intact (#4507)."""
import unittest

from tools.quant_quality import engine_args


class VisionValue(unittest.TestCase):
def test_quant_quality_keeps_valued_vision(self):
base = ["--pack", "/p", "--eos", "1"]
for vision in (["--vision", "off"], ["--vision", "on"], ["--vision"]):
for tail in ([], ["--dspark", "none"]):
args = base + vision + tail
with self.subTest(vision=vision, tail=tail):
cfg = {"exe": "strata-dsv41", "arch": "deepseek41", "args": args}
expected = engine_args({**cfg, "args": base + tail}, None, 512)
if len(vision) == 2:
expected[2 + len(base):2 + len(base)] = vision
self.assertEqual(engine_args(cfg, None, 512), expected)
self.assertEqual(cfg["args"], args)
2 changes: 1 addition & 1 deletion tools/quant_quality.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def engine_args(cfg: dict, gpu_experts, seg_tokens: int) -> list[str]:
base, out, i = list(cfg["args"]), [], 0
while i < len(base):
x = base[i]
if x in DROP_FLAG:
if x in DROP_FLAG and not (x == "--vision" and i + 1 < len(base) and not base[i + 1].startswith("--")):
i += 1
continue
if x in DROP_VALUE:
Expand Down
Loading