Skip to content
Merged
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
7 changes: 5 additions & 2 deletions src/dlm/export/ollama/modelfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def render_modelfile(ctx: ModelfileContext) -> str:
)
from_line = f"FROM ./{ctx.base_gguf_name}"
adapter_line = f"ADAPTER ./{ctx.adapter_gguf_name}" if ctx.adapter_gguf_name else None
template_block = _build_template_block(template_row)
template_block = _build_template_block(template_row) if ctx.plan.include_template else None
num_ctx = resolve_num_ctx(ctx.training_sequence_len, ctx.spec.context_length)
temperature = (
ctx.override_temperature
Expand All @@ -121,7 +121,10 @@ def render_modelfile(ctx: ModelfileContext) -> str:
parts: list[str] = [header, "", from_line]
if adapter_line is not None:
parts.append(adapter_line)
parts.extend(["", template_block, ""])
if template_block is not None:
parts.extend(["", template_block, ""])
else:
parts.append("")
parts.extend(param_lines)
if system_line is not None:
parts.extend(["", system_line])
Expand Down
7 changes: 5 additions & 2 deletions src/dlm/export/ollama/vl_modelfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def render_vl_modelfile(ctx: VlModelfileContext) -> str:
)
from_line = f"FROM ./{ctx.base_gguf_name}"
adapter_line = f"ADAPTER ./{ctx.adapter_gguf_name}" if ctx.adapter_gguf_name else None
template_block = f'TEMPLATE """{_VL_TEMPLATE_BODY}"""'
template_block = f'TEMPLATE """{_VL_TEMPLATE_BODY}"""' if ctx.plan.include_template else None
num_ctx = resolve_num_ctx(ctx.training_sequence_len, ctx.spec.context_length)
temperature = (
ctx.override_temperature
Expand All @@ -152,7 +152,10 @@ def render_vl_modelfile(ctx: VlModelfileContext) -> str:
parts: list[str] = [header, "", from_line]
if adapter_line is not None:
parts.append(adapter_line)
parts.extend(["", template_block, ""])
if template_block is not None:
parts.extend(["", template_block, ""])
else:
parts.append("")
parts.extend(param_lines)
if system_line is not None:
parts.extend(["", system_line])
Expand Down
27 changes: 27 additions & 0 deletions tests/unit/export/ollama/test_modelfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,33 @@ def test_template_block_present(self, tmp_path: Path) -> None:
assert 'TEMPLATE """' in text
assert "<|im_start|>" in text # chatml dialect

def test_no_template_when_include_template_false(self, tmp_path: Path) -> None:
"""Audit 13 M13.1: ``--no-template`` must actually suppress the
TEMPLATE block in the emitted Modelfile, not just the preflight."""
ctx = _ctx(tmp_path)
# Bypass the frozen-dataclass replace dance: rebuild with a plan
# that has include_template=False.
plan = ExportPlan(quant="Q4_K_M", merged=False, include_template=False)
ctx_no_tmpl = ModelfileContext(
spec=ctx.spec,
plan=plan,
adapter_dir=ctx.adapter_dir,
base_gguf_name=ctx.base_gguf_name,
adapter_gguf_name=ctx.adapter_gguf_name,
dlm_id=ctx.dlm_id,
adapter_version=ctx.adapter_version,
system_prompt=ctx.system_prompt,
training_sequence_len=ctx.training_sequence_len,
override_temperature=ctx.override_temperature,
override_top_p=ctx.override_top_p,
draft_model_ollama_name=ctx.draft_model_ollama_name,
)
text = render_modelfile(ctx_no_tmpl)
assert "TEMPLATE" not in text
# Other directives still emit normally.
assert "FROM ./base.Q4_K_M.gguf" in text
assert "PARAMETER temperature" in text

def test_params_emitted(self, tmp_path: Path) -> None:
text = render_modelfile(_ctx(tmp_path))
assert "PARAMETER temperature" in text
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/export/ollama/test_vl_modelfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,21 @@ def test_blank_system_prompt_is_omitted(self, tmp_path: Path) -> None:

assert "SYSTEM " not in text

def test_no_template_when_include_template_false(self, tmp_path: Path) -> None:
"""`--no-template` skips TEMPLATE emission on the VL renderer."""
ctx = VlModelfileContext(
spec=_QWEN_VL_SPEC,
plan=ExportPlan(quant="Q4_K_M", merged=False, include_template=False),
adapter_dir=_adapter_dir(tmp_path),
base_gguf_name="base.Q4_K_M.gguf",
adapter_gguf_name="adapter.gguf",
dlm_id="01VLTEST",
adapter_version=4,
)
text = render_vl_modelfile(ctx)
assert "TEMPLATE" not in text
assert "FROM ./base.Q4_K_M.gguf" in text


class TestVlStopsFromAdapter:
def test_family_defaults_and_adapter_special_tokens_are_merged(self, tmp_path: Path) -> None:
Expand Down
19 changes: 17 additions & 2 deletions tests/unit/export/test_vl_modelfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ def _fake_vl_spec() -> Any:
)


def _fake_plan() -> Any:
def _fake_plan(*, include_template: bool = True) -> Any:
from types import SimpleNamespace

return SimpleNamespace(quant="Q4_K_M", merged=False)
return SimpleNamespace(quant="Q4_K_M", merged=False, include_template=include_template)


@pytest.fixture
Expand Down Expand Up @@ -166,6 +166,21 @@ def test_ends_with_newline(self, vl_ctx: VlModelfileContext) -> None:
out = render_vl_modelfile(vl_ctx)
assert out.endswith("\n")

def test_no_template_when_include_template_false(self, adapter_dir: Path) -> None:
"""`--no-template` skips TEMPLATE emission on the VL path too."""
ctx = VlModelfileContext(
spec=_fake_vl_spec(),
plan=_fake_plan(include_template=False),
adapter_dir=adapter_dir,
base_gguf_name="base.Q4_K_M.gguf",
adapter_gguf_name="adapter.Q4_K_M.gguf",
dlm_id="01JZZZZZZZZZZZZZZZZZZZZZZZ",
adapter_version=1,
)
out = render_vl_modelfile(ctx)
assert "TEMPLATE" not in out
assert "FROM ./base.Q4_K_M.gguf" in out


class TestStopsFallback:
def test_paligemma_uses_gemma_style_stop(self, tmp_path: Path) -> None:
Expand Down
Loading