Skip to content
Open
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
22 changes: 12 additions & 10 deletions maya.py
Original file line number Diff line number Diff line change
Expand Up @@ -5857,9 +5857,9 @@ def ds4_vision_model(mmproj: bool = False) -> dict:
"download_gb": sum(v[0] for v in man["files"].values()) / 1e9}


def ds4_vision_dir(d: Path) -> Path:
"""The vision tower's folder: beside the GGUFs' folders (as the drafter's), shared by every quant there."""
return d.parent / "vision"
def ds4_vision_dir(d: Path, models: Path | None = None) -> Path:
"""The shared vision folder; a model directly in --models-dir keeps it inside that folder."""
return (d if models is not None and d == models else d.parent) / "vision"


def ds4_pack_has_vision(pack: Path) -> bool:
Expand Down Expand Up @@ -6444,7 +6444,9 @@ def ds4_pack_step(a, d: Path, gguf: bool = False, announce: bool = True, engram:
shards += sorted(engram.glob("*.gguf"))
drafter_new = gguf and (drafter or d.parent / "dspark" / "dspark.json").is_file() and not CDS.has_drafter(
{"args": ["--pack", str(pack)]}) # (the drafter arrived after the pack was built)
vision_new = (gguf and (ds4_vision_dir(d) / "vision.json").is_file() and not ds4_pack_has_vision(pack)) or (
if gguf and vision_dir is None:
vision_dir = ds4_vision_dir(d)
vision_new = (gguf and (vision_dir / "vision.json").is_file() and not ds4_pack_has_vision(pack)) or (
not gguf and vision_dir is not None and not ds4_pack_tower(pack))
if not a.repack and read_json(pack / PACK_SOURCES).get("tools") == tools and not drafter_new and \
not vision_new and all((pack / f).exists() for f in need) and pack_stale(pack, shards) is None:
Expand All @@ -6456,8 +6458,7 @@ def ds4_pack_step(a, d: Path, gguf: bool = False, announce: bool = True, engram:
"Engram hash tables and the")
say(" tokenizer (about a minute) ...")
run([sys.executable, str(ROOT / "tools" / "ds4" / ("pack_gguf.py" if gguf else "pack.py")), "--model", str(d),
"--out", str(pack)] + (["--vision", str(ds4_vision_dir(d))] if gguf else
["--vision", str(vision_dir)] if vision_dir is not None else []) +
"--out", str(pack)] + (["--vision", str(vision_dir)] if vision_dir is not None else []) +
(["--engram", str(engram)] if gguf and engram is not None else []) +
(["--drafter", str(drafter)] if gguf and drafter is not None else []) +
(["--shards"] + [Path(f).name for f in files] if gguf and files else []) +
Expand Down Expand Up @@ -6641,13 +6642,14 @@ def set_up_ds4(a, prev: dict) -> Path | None:
own = ds4_quant_drafter(quant) if gguf else None # (Maya-XS: its own drafter beside the shared one)
dj = d.parent / "dspark" / own["json"] if own is not None and drafter else None
tower = None if gguf or a.no_vision else DS4_EXL3[quant].get("tower") # (DeepSeek's BF16 tower for the quant's own)
vdir = ds4_exl3_vision_dir(models) if tower else None
vdir = ds4_vision_dir(d, models) if gguf else ds4_exl3_vision_dir(models) if tower else None
pack = ds4_pack_step(a, d, gguf, engram=engram, files=files, drafter=dj, without=without,
vision_dir=vdir if vdir is not None and (vdir / "vision.bin").is_file() else None) # 6
vision_dir=vdir if gguf or vdir is not None and (vdir / "vision.bin").is_file() else None) # 6
if gguf: # 7 (DeepSeek's checkpoint's tower, added to the pack)
vision = ds4_vision_step(a, pc, d, mmproj=quant in DS4_UD) # (UD quants: unsloth's mmproj, the same tower)
vision = ds4_vision_step(a, pc, d, mmproj=quant in DS4_UD, v=vdir) # (UD quants: unsloth's mmproj, the same tower)
if vision and not ds4_pack_has_vision(pack):
pack = ds4_pack_step(a, d, gguf, announce=False, engram=engram, files=files, drafter=dj, without=without)
pack = ds4_pack_step(a, d, gguf, announce=False, engram=engram, files=files, drafter=dj, without=without,
vision_dir=vdir)
vision = vision and ds4_pack_has_vision(pack)
elif tower: # 7 (the quant's own tower is EXL3: DeepSeek's BF16 one instead)
vision = ds4_vision_step(a, pc, d, v=vdir)
Expand Down
36 changes: 36 additions & 0 deletions tools/test_setup_ds4.py
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,42 @@ def test_folder_is_shared_by_the_quants(self):
self.assertEqual(self.v, self.models / "DeepSeek-V4.1-Flash-1017-GGUF" / "vision")
self.assertEqual(maya.ds4_vision_dir(self.d.parent / "UD-Q4_K_XL"), self.v)

def test_setup_keeps_flat_model_vision_inside_models_dir(self):
"""A retained pack directly in --models-dir must not download vision on its parent disk."""
shard = self.models / "model.gguf"
shard.write_bytes(b"g")
pack = self.models / "maya-ds4"
previous = {"args": ["--pack", str(pack)], "installer": {"ds4_quant": "maya-s"}}
with patch.object(maya, "check_pc", return_value={"gpus": [{"index": 0}]}), \
patch.object(maya, "choose_context", return_value=65536), \
patch.object(maya, "tools_step", return_value=None), patch.object(maya, "build_step", return_value={}), \
patch.object(maya, "ds4_earlier", return_value=None), \
patch.object(maya, "ds4_upgrade_from", return_value=None), \
patch.object(maya, "ds4_shared_tables", return_value=None), \
patch.object(maya, "ds4_model_step", return_value=[shard]), \
patch.object(maya, "ds4_unused"), patch.object(maya, "ds4_drafter_step", return_value=False), \
patch.object(maya, "ds4_vision_step", return_value=True) as vision, \
patch.object(maya, "ds4_pack_step", return_value=pack) as packs, \
patch.object(maya, "ds4_pack_has_vision", return_value=False), \
patch.object(maya, "write_config_ds4", return_value=self.models / "maya-ds4.json"), \
patch.object(maya.CDS, "has_drafter", return_value=False):
maya.set_up_ds4(args(ds4_quant="maya-s", models_dir=str(self.models)), previous)
self.assertEqual(vision.call_args.kwargs.get("v"), self.models / "vision")
self.assertEqual(len(packs.call_args_list), 2)
for call in packs.call_args_list:
self.assertEqual(call.kwargs.get("vision_dir"), self.models / "vision")

def test_explicit_vision_dir_is_passed_to_gguf_pack(self):
pack = self.d / "maya-ds4"
(pack / "tokenizer").mkdir(parents=True)
for f in ("ds4.txt", "tensors.txt", "engram.bin", "tokenizer/vocab.json", "tokenizer/chat_template.jinja"):
(pack / f).write_text("hidden_size 4096\n")
target = self.d / "vision"
with patch.object(maya, "run") as run:
maya.ds4_pack_step(args(repack=True), self.d, gguf=True, vision_dir=target)
command = run.call_args.args[0]
self.assertEqual(command[command.index("--vision") + 1], str(target))

def test_no_vision_downloads_nothing(self):
with patch.object(maya, "offer_download", side_effect=AssertionError("asked")):
self.assertFalse(maya.ds4_vision_step(args(no_vision=True), {}, self.d))
Expand Down