File size: 4,960 Bytes
79a20c7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
from __future__ import annotations

from dataclasses import replace
from pathlib import Path

import pytest

from dlb.adapters.candi import CANDIAdapter
from dlb.adapters.di4c import Di4CAdapter
from dlb.adapters.duo import DuoAdapter
from dlb.adapters.flm import FLMAdapter
from dlb.adapters.langflow import LangFlowAdapter
from dlb.adapters.mdlm import MDLMAdapter
from dlb.adapters.rdlm import RDLMAdapter
from dlb.adapters.sdtt import SDTTAdapter
from dlb.runner import RunRequest


ROOT = Path(__file__).parents[1]
MANIFEST = ROOT / "data/manifests/conditional-lm1b-c64.json"


def conditional_request(model: str, dataset: str = "lm1b", steps: int = 8) -> RunRequest:
    step_count = 1000 if model == "rdlm" else steps
    return RunRequest(
        run_id=f"{model}-{dataset}-steps-{step_count}",
        model_id=model,
        dataset_id=dataset,
        step_count=step_count,
        seed=42,
        sample_count=2048,
        generation_mode="conditional_prefix",
        conditioning_manifest=str(MANIFEST),
        conditioning_manifest_sha256="a" * 64,
        conditioning_config_sha256="b" * 64,
        prefix_length=64,
        evaluation_continuation_length=64,
        prompt_count=1024,
        diversity_prompt_count=256,
        completions_per_diversity_prompt=5,
        completion_schedule="c0:p0-1023;c1-4:p0-255",
        results_root=str(ROOT / "results/conditional"),
    )


def run_dir(item: RunRequest) -> Path:
    return (
        ROOT
        / "results"
        / "conditional"
        / "samples"
        / item.dataset_id
        / item.model_id
        / f"steps_{item.step_count}"
    )


def option(command: list[str], key: str) -> str:
    index = command.index(key)
    return command[index + 1]


def wrapper_option(command: list[str], key: str) -> str:
    prefix = key + "="
    values = [argument[len(prefix) :] for argument in command if argument.startswith(prefix)]
    assert len(values) == 1, (key, command)
    return values[0]


@pytest.mark.parametrize(
    ("model", "adapter"),
    [
        ("flm", FLMAdapter()),
        ("fmlm", FLMAdapter()),
        ("duo", DuoAdapter()),
        ("duo_dcd", DuoAdapter()),
        ("mdlm", MDLMAdapter()),
        ("candi", CANDIAdapter()),
        ("langflow", LangFlowAdapter()),
        ("rdlm", RDLMAdapter()),
    ],
)
def test_teacher_command_serializes_complete_conditioning_contract(model: str, adapter) -> None:
    request = conditional_request(model)

    command = adapter.render_command(request, run_dir(request), dry_run=True)

    assert wrapper_option(command, "--generation-mode") == "conditional_prefix"
    assert wrapper_option(command, "--conditioning-manifest") == str(MANIFEST)
    assert wrapper_option(command, "--conditioning-manifest-sha256") == "a" * 64
    assert wrapper_option(command, "--prefix-length") == "64"
    assert wrapper_option(command, "--prompt-count") == "1024"
    assert wrapper_option(command, "--diversity-prompt-count") == "256"
    assert wrapper_option(command, "--completions-per-diversity-prompt") == "5"
    assert wrapper_option(command, "--completion-schedule") == "c0:p0-1023;c1-4:p0-255"


@pytest.mark.parametrize(
    ("model", "adapter"),
    [
        ("mdlm_sdtt", SDTTAdapter()),
        ("mdlm_di4c", Di4CAdapter("mdlm")),
        ("duo_di4c", Di4CAdapter("duo")),
    ],
)
def test_distilled_command_serializes_complete_conditioning_contract(model: str, adapter) -> None:
    request = conditional_request(model)

    command = adapter.render_command(request, run_dir(request), dry_run=True)

    assert option(command, "--generation-mode") == "conditional_prefix"
    assert option(command, "--conditioning-manifest") == str(MANIFEST)
    assert option(command, "--conditioning-manifest-sha256") == "a" * 64
    assert option(command, "--prefix-length") == "64"
    assert option(command, "--prompt-count") == "1024"
    assert option(command, "--diversity-prompt-count") == "256"
    assert option(command, "--completions-per-diversity-prompt") == "5"
    assert option(command, "--completion-schedule") == "c0:p0-1023;c1-4:p0-255"


def test_unconditional_command_does_not_emit_conditioning_flags() -> None:
    request = replace(conditional_request("mdlm"), generation_mode="unconditional")
    request = replace(
        request,
        conditioning_manifest=None,
        conditioning_manifest_sha256=None,
        conditioning_config_sha256=None,
        prefix_length=None,
        evaluation_continuation_length=None,
        prompt_count=None,
        diversity_prompt_count=None,
        completions_per_diversity_prompt=None,
        completion_schedule=None,
        results_root=None,
        sample_count=17,
    )

    command = MDLMAdapter().render_command(
        request,
        ROOT / "results" / "samples" / "lm1b" / "mdlm" / "steps_8",
        dry_run=True,
    )

    assert not any("conditioning" in argument or "generation-mode" in argument for argument in command)