Add files using upload-large-folder tool
Browse files- LTA_openwebtext_dualt/scripts/_tmp_flowtext_decode_lab_nospecial_prompt.py +484 -0
- LTA_openwebtext_dualt/scripts/eval_lm1b_linear_simplex_genppl.py +314 -0
- LTA_openwebtext_dualt/scripts/eval_train8_overfit_sweep.sh +54 -0
- LTA_openwebtext_dualt/scripts/launch_ar_openwebtext_duo_small_8gpu_1m.sh +99 -0
- LTA_openwebtext_dualt/scripts/launch_lm1b_flm_8gpu_repro_20260506.sh +123 -0
- LTA_openwebtext_dualt/scripts/launch_lta_lm1b_categorical_fullvocab_c1024_gaussian_linear_mean_fullycoupled_8gpu_small_1m.sh +156 -0
- LTA_openwebtext_dualt/scripts/launch_lta_lm1b_compact_gpt2bpe_v8192_len128_fullycoupled_4gpu.sh +219 -0
- LTA_openwebtext_dualt/scripts/launch_lta_openwebtext_dualt_8gpu_aligned.sh +113 -0
- LTA_openwebtext_dualt/scripts/launch_lta_owt_compact_gpt2bpe_v2048_elfaligned_logitnormal_tokenized_8gpu.sh +34 -0
- LTA_openwebtext_dualt/scripts/launch_lta_owt_fullycoupled_logitnormal_mid_mask1_wd0p1_fp32_8gpu.sh +204 -0
- LTA_openwebtext_dualt/scripts/launch_lta_owt_t5_adaln_adamw_wd0p1_rollin_grad_k1_rho025_8gpu.sh +168 -0
- LTA_openwebtext_dualt/scripts/make_duo_integral_cache.py +77 -0
- LTA_openwebtext_dualt/scripts/prepare_elf_wmt14_deen_t5.sh +32 -0
- LTA_openwebtext_dualt/scripts/run_lta_lm1b_bert_absrope_time4_dirichlet_len128_C1_to_1024_4gpu_1m_mask1_sameT_save1k.sh +29 -0
- LTA_openwebtext_dualt/scripts/run_lta_owt_dirichlet_len1024_Cv_to_2v_4gpu_abspos_specialloss_watch.sh +42 -0
- LTA_openwebtext_dualt/scripts/run_lta_owt_dirichlet_len1024_Cv_to_2v_8gpu_save1k_with_gumbel_watch.sh +404 -0
- LTA_openwebtext_dualt/scripts/run_lta_owt_t5_len128_uniform10k_then_lognsr_4gpu.sh +60 -0
- LTA_openwebtext_dualt/scripts/run_train8_ctx1024_sampleds_sweep_4gpu.sh +282 -0
- LTA_openwebtext_dualt/scripts/run_train8_decode_algo_sweep_len256_latest.sh +113 -0
- LTA_openwebtext_dualt/scripts/sweep_categorical_c1024_late_refresh_20260506.py +281 -0
LTA_openwebtext_dualt/scripts/_tmp_flowtext_decode_lab_nospecial_prompt.py
ADDED
|
@@ -0,0 +1,484 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Decode-sweep lab for FlowText OpenWebText checkpoints.
|
| 3 |
+
|
| 4 |
+
The goal is to debug inference without touching training. We try several
|
| 5 |
+
simplex-valid update rules, generate many candidates, and rank them with
|
| 6 |
+
anti-collapse diagnostics instead of pure self-likelihood.
|
| 7 |
+
|
| 8 |
+
Run from the flowtext_standard_bench repository root.
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
from __future__ import annotations
|
| 12 |
+
|
| 13 |
+
import argparse
|
| 14 |
+
import json
|
| 15 |
+
import math
|
| 16 |
+
import re
|
| 17 |
+
import sys
|
| 18 |
+
from collections import Counter
|
| 19 |
+
from dataclasses import dataclass, asdict
|
| 20 |
+
from pathlib import Path
|
| 21 |
+
from typing import Iterable, List, Sequence
|
| 22 |
+
|
| 23 |
+
import torch
|
| 24 |
+
import torch.nn.functional as F
|
| 25 |
+
|
| 26 |
+
REPO_ROOT = Path(__file__).resolve().parents[1]
|
| 27 |
+
if str(REPO_ROOT) not in sys.path:
|
| 28 |
+
sys.path.insert(0, str(REPO_ROOT))
|
| 29 |
+
|
| 30 |
+
from eval import build_model_from_ckpt
|
| 31 |
+
from flowtext_lab.bridges import smooth_onehot
|
| 32 |
+
from flowtext_lab.decode import model_time_for_step, sample_noise_simplex, state_for_model
|
| 33 |
+
from flowtext_lab.tokenization import BpeTextTokenizer
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
WORD_RE = re.compile(r"[A-Za-z]+|\d+|[^\sA-Za-z\d]")
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
@dataclass
|
| 40 |
+
class DecodeConfig:
|
| 41 |
+
label: str
|
| 42 |
+
rule: str
|
| 43 |
+
steps: int = 64
|
| 44 |
+
model_t_mode: str = "flow"
|
| 45 |
+
eta: float = 0.5
|
| 46 |
+
damping: float = 1.0
|
| 47 |
+
max_gamma: float = 1.0
|
| 48 |
+
endpoint_temp: float = 1.0
|
| 49 |
+
state_floor: float = 1e-8
|
| 50 |
+
final_from: str = "state"
|
| 51 |
+
noise_mix: float = 0.0
|
| 52 |
+
noise_decay: str = "linear"
|
| 53 |
+
eos_logit_bias: float = 0.0
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def tokenize_for_metrics(text: str) -> list[str]:
|
| 57 |
+
return WORD_RE.findall(text)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def repeated_ngram_frac(tokens: Sequence[str], n: int) -> float:
|
| 61 |
+
if len(tokens) < n:
|
| 62 |
+
return 0.0
|
| 63 |
+
grams = list(zip(*[tokens[i:] for i in range(n)]))
|
| 64 |
+
counts = Counter(grams)
|
| 65 |
+
return sum(v - 1 for v in counts.values() if v > 1) / max(len(grams), 1)
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def text_metrics(text: str) -> dict:
|
| 69 |
+
toks = tokenize_for_metrics(text)
|
| 70 |
+
words = [t.lower() for t in toks if re.fullmatch(r"[A-Za-z]+", t)]
|
| 71 |
+
n_tok = max(len(toks), 1)
|
| 72 |
+
n_words = max(len(words), 1)
|
| 73 |
+
word_counts = Counter(words)
|
| 74 |
+
max_word_frac = word_counts.most_common(1)[0][1] / n_words if word_counts else 1.0
|
| 75 |
+
distinct1 = len(set(words)) / n_words if words else 0.0
|
| 76 |
+
bigrams = list(zip(words, words[1:]))
|
| 77 |
+
distinct2 = len(set(bigrams)) / max(len(bigrams), 1) if bigrams else 0.0
|
| 78 |
+
digit_frac = sum(t.isdigit() for t in toks) / n_tok
|
| 79 |
+
punct_frac = sum(bool(re.fullmatch(r"[,.;:!?]+", t)) for t in toks) / n_tok
|
| 80 |
+
eos_count = text.count("<|endoftext|>")
|
| 81 |
+
bad_char_count = text.count("�")
|
| 82 |
+
rep3 = repeated_ngram_frac([t.lower() for t in toks], 3)
|
| 83 |
+
rep4 = repeated_ngram_frac([t.lower() for t in toks], 4)
|
| 84 |
+
# This score is deliberately simple and non-oracle. It rewards length and
|
| 85 |
+
# lexical variety while heavily penalizing classic collapse artifacts.
|
| 86 |
+
quality = (
|
| 87 |
+
min(len(text) / 700.0, 1.0)
|
| 88 |
+
+ 0.35 * distinct2
|
| 89 |
+
+ 0.15 * distinct1
|
| 90 |
+
- 0.30 * eos_count
|
| 91 |
+
- 2.60 * rep3
|
| 92 |
+
- 1.60 * rep4
|
| 93 |
+
- 1.30 * digit_frac
|
| 94 |
+
- 0.65 * punct_frac
|
| 95 |
+
- 1.35 * max_word_frac
|
| 96 |
+
- 0.35 * bad_char_count
|
| 97 |
+
)
|
| 98 |
+
return {
|
| 99 |
+
"quality": float(quality),
|
| 100 |
+
"chars": len(text),
|
| 101 |
+
"tokens": len(toks),
|
| 102 |
+
"words": len(words),
|
| 103 |
+
"eos_count": eos_count,
|
| 104 |
+
"bad_char_count": bad_char_count,
|
| 105 |
+
"rep3": float(rep3),
|
| 106 |
+
"rep4": float(rep4),
|
| 107 |
+
"distinct1": float(distinct1),
|
| 108 |
+
"distinct2": float(distinct2),
|
| 109 |
+
"digit_frac": float(digit_frac),
|
| 110 |
+
"punct_frac": float(punct_frac),
|
| 111 |
+
"max_word_frac": float(max_word_frac),
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def decode_text(tokenizer: BpeTextTokenizer, ids: Sequence[int]) -> str:
|
| 116 |
+
return tokenizer.decode(ids, stop_at_eos=False, skip_special_tokens=False)
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
def encode_prompt(tokenizer: BpeTextTokenizer, prompt: str, max_len: int) -> list[int]:
|
| 120 |
+
# Prefix-continuation mode: lock [CLS] + prompt tokens, but do NOT lock an early [SEP].
|
| 121 |
+
# tokenizers.Tokenizer.encode(..., add_special_tokens=False) avoids the default BERT wrapper.
|
| 122 |
+
core = list(tokenizer.tokenizer.encode(prompt, add_special_tokens=False).ids)
|
| 123 |
+
bos = tokenizer.bos_id
|
| 124 |
+
ids = ([bos] if bos is not None and bos >= 0 else []) + core
|
| 125 |
+
return ids[:max_len]
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
@torch.no_grad()
|
| 129 |
+
def build_initial_state(
|
| 130 |
+
tokenizer: BpeTextTokenizer,
|
| 131 |
+
prompts: list[str],
|
| 132 |
+
restarts: int,
|
| 133 |
+
max_len: int,
|
| 134 |
+
target_prob: float,
|
| 135 |
+
eps: float,
|
| 136 |
+
noise_init: str,
|
| 137 |
+
noise_sigma: float,
|
| 138 |
+
dirichlet_init_concentration: float,
|
| 139 |
+
device: torch.device,
|
| 140 |
+
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, list[str]]:
|
| 141 |
+
expanded: list[str] = []
|
| 142 |
+
prompt_ids: list[list[int]] = []
|
| 143 |
+
for prompt in prompts:
|
| 144 |
+
ids = encode_prompt(tokenizer, prompt, max_len=max_len)
|
| 145 |
+
for _ in range(restarts):
|
| 146 |
+
expanded.append(prompt)
|
| 147 |
+
prompt_ids.append(ids)
|
| 148 |
+
|
| 149 |
+
batch = len(prompt_ids)
|
| 150 |
+
attn = torch.ones((batch, max_len), dtype=torch.bool, device=device)
|
| 151 |
+
probs = sample_noise_simplex(
|
| 152 |
+
(batch, max_len),
|
| 153 |
+
tokenizer.vocab_size,
|
| 154 |
+
device,
|
| 155 |
+
eps,
|
| 156 |
+
noise_mode=noise_init,
|
| 157 |
+
target_prob=target_prob,
|
| 158 |
+
noise_sigma=noise_sigma,
|
| 159 |
+
dirichlet_concentration=dirichlet_init_concentration,
|
| 160 |
+
)
|
| 161 |
+
lock = torch.zeros((batch, max_len), dtype=torch.bool, device=device)
|
| 162 |
+
lock_probs = torch.zeros((batch, max_len, tokenizer.vocab_size), dtype=torch.float32, device=device)
|
| 163 |
+
for row, ids in enumerate(prompt_ids):
|
| 164 |
+
if not ids:
|
| 165 |
+
continue
|
| 166 |
+
ids_t = torch.tensor(ids, dtype=torch.long, device=device).unsqueeze(0)
|
| 167 |
+
sp = smooth_onehot(ids_t, tokenizer.vocab_size, target_prob, eps)[0]
|
| 168 |
+
probs[row, : len(ids)] = sp
|
| 169 |
+
lock_probs[row, : len(ids)] = sp
|
| 170 |
+
lock[row, : len(ids)] = True
|
| 171 |
+
return probs, attn, lock, lock_probs, expanded
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
def flowmap_gamma(step: int, steps: int, damping: float, max_gamma: float, eps: float) -> float:
|
| 175 |
+
s = step / max(steps, 1)
|
| 176 |
+
t_next = (step + 1) / max(steps, 1)
|
| 177 |
+
base_gamma = (t_next - s) / max(1.0 - s, eps)
|
| 178 |
+
gamma = float(damping) * base_gamma
|
| 179 |
+
return min(gamma, float(max_gamma)) if max_gamma > 0 else gamma
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
@torch.no_grad()
|
| 183 |
+
def decode_batch(
|
| 184 |
+
model,
|
| 185 |
+
init_probs: torch.Tensor,
|
| 186 |
+
attn: torch.Tensor,
|
| 187 |
+
lock: torch.Tensor,
|
| 188 |
+
lock_probs: torch.Tensor,
|
| 189 |
+
cfg: DecodeConfig,
|
| 190 |
+
eps: float,
|
| 191 |
+
eos_id: int | None = None,
|
| 192 |
+
) -> torch.Tensor:
|
| 193 |
+
probs = init_probs.float().clone()
|
| 194 |
+
device = probs.device
|
| 195 |
+
last_endpoint = probs
|
| 196 |
+
for step in range(cfg.steps):
|
| 197 |
+
t = model_time_for_step(cfg.model_t_mode, step, cfg.steps, probs.size(0), device, dtype=torch.float32)
|
| 198 |
+
logits = model(state_for_model(model, probs, eps), t, attn).float()
|
| 199 |
+
if cfg.endpoint_temp != 1.0:
|
| 200 |
+
logits = logits / float(cfg.endpoint_temp)
|
| 201 |
+
if cfg.eos_logit_bias != 0.0 and eos_id is not None and 0 <= eos_id < logits.size(-1):
|
| 202 |
+
logits[..., eos_id] = logits[..., eos_id] + float(cfg.eos_logit_bias)
|
| 203 |
+
endpoint = F.softmax(logits, dim=-1)
|
| 204 |
+
last_endpoint = endpoint
|
| 205 |
+
|
| 206 |
+
if cfg.rule == "flowmap":
|
| 207 |
+
gamma = flowmap_gamma(step, cfg.steps, cfg.damping, cfg.max_gamma, eps)
|
| 208 |
+
new_probs = probs + gamma * (endpoint - probs)
|
| 209 |
+
elif cfg.rule == "replace":
|
| 210 |
+
new_probs = (1.0 - cfg.eta) * probs + cfg.eta * endpoint
|
| 211 |
+
elif cfg.rule == "geometric":
|
| 212 |
+
log_mix = (1.0 - cfg.eta) * torch.log(probs.clamp_min(eps)) + cfg.eta * torch.log(endpoint.clamp_min(eps))
|
| 213 |
+
new_probs = F.softmax(log_mix, dim=-1)
|
| 214 |
+
elif cfg.rule == "centered_residual":
|
| 215 |
+
# Add a zero-sum probability residual, then project back to simplex.
|
| 216 |
+
residual = endpoint - probs
|
| 217 |
+
residual = residual - residual.mean(dim=-1, keepdim=True)
|
| 218 |
+
new_probs = probs + cfg.eta * residual
|
| 219 |
+
else:
|
| 220 |
+
raise ValueError(f"Unknown decode rule: {cfg.rule}")
|
| 221 |
+
|
| 222 |
+
if cfg.noise_mix > 0:
|
| 223 |
+
if cfg.noise_decay == "linear":
|
| 224 |
+
lam = cfg.noise_mix * (1.0 - (step + 1) / max(cfg.steps, 1))
|
| 225 |
+
elif cfg.noise_decay == "sqrt":
|
| 226 |
+
lam = cfg.noise_mix * math.sqrt(max(0.0, 1.0 - (step + 1) / max(cfg.steps, 1)))
|
| 227 |
+
else:
|
| 228 |
+
lam = cfg.noise_mix
|
| 229 |
+
if lam > 0:
|
| 230 |
+
uniform = torch.full_like(new_probs, 1.0 / new_probs.size(-1))
|
| 231 |
+
new_probs = (1.0 - lam) * new_probs + lam * uniform
|
| 232 |
+
|
| 233 |
+
new_probs = new_probs.clamp_min(max(float(cfg.state_floor), eps))
|
| 234 |
+
new_probs = new_probs / new_probs.sum(dim=-1, keepdim=True).clamp_min(eps)
|
| 235 |
+
new_probs = torch.where(lock.unsqueeze(-1), lock_probs, new_probs)
|
| 236 |
+
probs = new_probs
|
| 237 |
+
|
| 238 |
+
if cfg.final_from == "endpoint":
|
| 239 |
+
out = last_endpoint
|
| 240 |
+
out = torch.where(lock.unsqueeze(-1), lock_probs, out)
|
| 241 |
+
return out / out.sum(dim=-1, keepdim=True).clamp_min(eps)
|
| 242 |
+
if cfg.final_from == "blend":
|
| 243 |
+
out = 0.5 * probs + 0.5 * last_endpoint
|
| 244 |
+
out = torch.where(lock.unsqueeze(-1), lock_probs, out)
|
| 245 |
+
return out / out.sum(dim=-1, keepdim=True).clamp_min(eps)
|
| 246 |
+
return probs
|
| 247 |
+
|
| 248 |
+
|
| 249 |
+
@torch.no_grad()
|
| 250 |
+
def pseudo_likelihood_scores(
|
| 251 |
+
model,
|
| 252 |
+
tokenizer: BpeTextTokenizer,
|
| 253 |
+
probs: torch.Tensor,
|
| 254 |
+
attn: torch.Tensor,
|
| 255 |
+
lock: torch.Tensor,
|
| 256 |
+
target_prob: float,
|
| 257 |
+
eps: float,
|
| 258 |
+
repeats: int,
|
| 259 |
+
mask_frac: float,
|
| 260 |
+
rerank_t: float,
|
| 261 |
+
) -> torch.Tensor:
|
| 262 |
+
ids = probs.argmax(dim=-1)
|
| 263 |
+
endpoint = smooth_onehot(ids, tokenizer.vocab_size, target_prob, eps)
|
| 264 |
+
eligible = attn & (~lock)
|
| 265 |
+
scores = torch.zeros(ids.size(0), dtype=torch.float32, device=ids.device)
|
| 266 |
+
counts = torch.zeros_like(scores)
|
| 267 |
+
for _ in range(max(1, repeats)):
|
| 268 |
+
score_mask = (torch.rand_like(ids.float()) < mask_frac) & eligible
|
| 269 |
+
for row in range(ids.size(0)):
|
| 270 |
+
if eligible[row].any() and not score_mask[row].any():
|
| 271 |
+
choices = torch.nonzero(eligible[row], as_tuple=False).flatten()
|
| 272 |
+
score_mask[row, choices[torch.randint(0, choices.numel(), (1,), device=ids.device)]] = True
|
| 273 |
+
noise = sample_noise_simplex(
|
| 274 |
+
(ids.size(0), ids.size(1)),
|
| 275 |
+
tokenizer.vocab_size,
|
| 276 |
+
ids.device,
|
| 277 |
+
eps,
|
| 278 |
+
noise_mode="logistic_normal",
|
| 279 |
+
target_prob=target_prob,
|
| 280 |
+
noise_sigma=-1.0,
|
| 281 |
+
)
|
| 282 |
+
inp = torch.where(score_mask.unsqueeze(-1), noise, endpoint)
|
| 283 |
+
inp = torch.where(lock.unsqueeze(-1), probs, inp)
|
| 284 |
+
t = torch.full((ids.size(0),), float(rerank_t), dtype=torch.float32, device=ids.device)
|
| 285 |
+
logits = model(state_for_model(model, inp, eps), t, attn).float()
|
| 286 |
+
logp = F.log_softmax(logits, dim=-1).gather(-1, ids.unsqueeze(-1)).squeeze(-1)
|
| 287 |
+
scores += (logp * score_mask.float()).sum(dim=-1)
|
| 288 |
+
counts += score_mask.float().sum(dim=-1)
|
| 289 |
+
return scores / counts.clamp_min(1.0)
|
| 290 |
+
|
| 291 |
+
|
| 292 |
+
def default_configs(steps: int, config_set: str) -> list[DecodeConfig]:
|
| 293 |
+
if config_set == "focused_flowmap":
|
| 294 |
+
return [
|
| 295 |
+
DecodeConfig("flowmap_t1p00_d1p0", "flowmap", steps=steps, damping=1.0, max_gamma=1.0),
|
| 296 |
+
DecodeConfig("flowmap_t1p10_d1p0", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.10),
|
| 297 |
+
DecodeConfig("flowmap_t1p25_d1p0", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.25),
|
| 298 |
+
DecodeConfig("flowmap_t1p40_d1p0", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.40),
|
| 299 |
+
DecodeConfig("flowmap_t1p60_d1p0", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.60),
|
| 300 |
+
DecodeConfig("flowmap_t1p25_d0p7", "flowmap", steps=steps, damping=0.7, max_gamma=1.0, endpoint_temp=1.25),
|
| 301 |
+
DecodeConfig("flowmap_t1p40_d0p7", "flowmap", steps=steps, damping=0.7, max_gamma=1.0, endpoint_temp=1.40),
|
| 302 |
+
DecodeConfig("flowmap_t1p60_d0p7", "flowmap", steps=steps, damping=0.7, max_gamma=1.0, endpoint_temp=1.60),
|
| 303 |
+
DecodeConfig("flowmap_t1p25_g0p5", "flowmap", steps=steps, damping=1.0, max_gamma=0.5, endpoint_temp=1.25),
|
| 304 |
+
DecodeConfig("flowmap_t1p40_g0p5", "flowmap", steps=steps, damping=1.0, max_gamma=0.5, endpoint_temp=1.40),
|
| 305 |
+
]
|
| 306 |
+
if config_set == "best_flowmap":
|
| 307 |
+
return [
|
| 308 |
+
DecodeConfig("flowmap_t1p25_d0p7", "flowmap", steps=steps, damping=0.7, max_gamma=1.0, endpoint_temp=1.25),
|
| 309 |
+
DecodeConfig("flowmap_t1p25_d1p0", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.25),
|
| 310 |
+
DecodeConfig("flowmap_t1p35_d1p0", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.35),
|
| 311 |
+
DecodeConfig("flowmap_t1p40_d1p0", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.40),
|
| 312 |
+
]
|
| 313 |
+
if config_set == "final_projection":
|
| 314 |
+
return [
|
| 315 |
+
DecodeConfig("flowmap_t1p35_state", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.35, final_from="state"),
|
| 316 |
+
DecodeConfig("flowmap_t1p35_endpoint", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.35, final_from="endpoint"),
|
| 317 |
+
DecodeConfig("flowmap_t1p35_blend", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.35, final_from="blend"),
|
| 318 |
+
DecodeConfig("flowmap_t1p40_state", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.40, final_from="state"),
|
| 319 |
+
DecodeConfig("flowmap_t1p40_endpoint", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.40, final_from="endpoint"),
|
| 320 |
+
DecodeConfig("flowmap_t1p40_blend", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.40, final_from="blend"),
|
| 321 |
+
DecodeConfig("flowmap_t1p25_d0p7_state", "flowmap", steps=steps, damping=0.7, max_gamma=1.0, endpoint_temp=1.25, final_from="state"),
|
| 322 |
+
DecodeConfig("flowmap_t1p25_d0p7_endpoint", "flowmap", steps=steps, damping=0.7, max_gamma=1.0, endpoint_temp=1.25, final_from="endpoint"),
|
| 323 |
+
DecodeConfig("flowmap_t1p25_d0p7_blend", "flowmap", steps=steps, damping=0.7, max_gamma=1.0, endpoint_temp=1.25, final_from="blend"),
|
| 324 |
+
]
|
| 325 |
+
if config_set == "eos_sweep":
|
| 326 |
+
return [
|
| 327 |
+
DecodeConfig("flowmap_t1p35_eos0", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.35, eos_logit_bias=0.0),
|
| 328 |
+
DecodeConfig("flowmap_t1p35_eos-1", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.35, eos_logit_bias=-1.0),
|
| 329 |
+
DecodeConfig("flowmap_t1p35_eos-2", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.35, eos_logit_bias=-2.0),
|
| 330 |
+
DecodeConfig("flowmap_t1p35_eos-3", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.35, eos_logit_bias=-3.0),
|
| 331 |
+
DecodeConfig("flowmap_t1p40_eos-2", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.40, eos_logit_bias=-2.0),
|
| 332 |
+
DecodeConfig("flowmap_t1p25_d0p7_eos-2", "flowmap", steps=steps, damping=0.7, max_gamma=1.0, endpoint_temp=1.25, eos_logit_bias=-2.0),
|
| 333 |
+
]
|
| 334 |
+
if config_set != "broad":
|
| 335 |
+
raise ValueError(f"Unknown config_set: {config_set}")
|
| 336 |
+
return [
|
| 337 |
+
DecodeConfig("flowmap64", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, final_from="state"),
|
| 338 |
+
DecodeConfig("flowmap_temp1p25", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=1.25),
|
| 339 |
+
DecodeConfig("flowmap_temp0p85", "flowmap", steps=steps, damping=1.0, max_gamma=1.0, endpoint_temp=0.85),
|
| 340 |
+
DecodeConfig("replace_eta0p35", "replace", steps=steps, eta=0.35),
|
| 341 |
+
DecodeConfig("replace_eta0p50", "replace", steps=steps, eta=0.50),
|
| 342 |
+
DecodeConfig("replace_eta0p65", "replace", steps=steps, eta=0.65),
|
| 343 |
+
DecodeConfig("replace_eta0p50_temp1p25", "replace", steps=steps, eta=0.50, endpoint_temp=1.25),
|
| 344 |
+
DecodeConfig("geometric_eta0p25", "geometric", steps=steps, eta=0.25),
|
| 345 |
+
DecodeConfig("geometric_eta0p50", "geometric", steps=steps, eta=0.50),
|
| 346 |
+
DecodeConfig("centered_residual_eta0p20", "centered_residual", steps=steps, eta=0.20),
|
| 347 |
+
DecodeConfig("replace_eta0p50_floor1e6", "replace", steps=steps, eta=0.50, state_floor=1e-6),
|
| 348 |
+
DecodeConfig("replace_eta0p50_leak", "replace", steps=steps, eta=0.50, noise_mix=0.03, noise_decay="sqrt"),
|
| 349 |
+
]
|
| 350 |
+
|
| 351 |
+
|
| 352 |
+
def aggregate(rows: list[dict]) -> dict:
|
| 353 |
+
keys = ["quality", "eos_count", "rep3", "rep4", "distinct1", "distinct2", "digit_frac", "max_word_frac"]
|
| 354 |
+
return {f"mean_{k}": sum(float(r[k]) for r in rows) / max(len(rows), 1) for k in keys}
|
| 355 |
+
|
| 356 |
+
|
| 357 |
+
def main() -> None:
|
| 358 |
+
parser = argparse.ArgumentParser()
|
| 359 |
+
parser.add_argument("--checkpoint", required=True)
|
| 360 |
+
parser.add_argument("--tokenizer_path", required=True)
|
| 361 |
+
parser.add_argument("--max_len", type=int, default=128)
|
| 362 |
+
parser.add_argument("--steps", type=int, default=64)
|
| 363 |
+
parser.add_argument("--restarts", type=int, default=64)
|
| 364 |
+
parser.add_argument("--target_prob", type=float, default=0.99)
|
| 365 |
+
parser.add_argument("--eps", type=float, default=1e-8)
|
| 366 |
+
parser.add_argument("--model_t_mode", choices=["linear", "flow", "const0", "const05", "const1", "random"], default="flow")
|
| 367 |
+
parser.add_argument("--noise_init", choices=["uniform", "logistic_normal", "dirichlet"], default="dirichlet")
|
| 368 |
+
parser.add_argument("--noise_sigma", type=float, default=-1.0)
|
| 369 |
+
parser.add_argument("--dirichlet_init_concentration", type=float, default=1.0)
|
| 370 |
+
parser.add_argument("--prompts", default="|The|In the early morning|Scientists have|The company said|A young woman")
|
| 371 |
+
parser.add_argument("--score_repeats", type=int, default=0)
|
| 372 |
+
parser.add_argument("--score_mask_frac", type=float, default=0.5)
|
| 373 |
+
parser.add_argument("--rerank_t", type=float, default=0.5)
|
| 374 |
+
parser.add_argument("--pl_weight", type=float, default=0.0)
|
| 375 |
+
parser.add_argument("--output", default="runs/decode_lab/latest_decode_lab.jsonl")
|
| 376 |
+
parser.add_argument("--config_set", default="broad", choices=["broad", "focused_flowmap", "best_flowmap", "final_projection", "eos_sweep"])
|
| 377 |
+
parser.add_argument("--decode_batch_size", type=int, default=0)
|
| 378 |
+
parser.add_argument("--topk", type=int, default=5)
|
| 379 |
+
parser.add_argument("--seed", type=int, default=20260428)
|
| 380 |
+
args = parser.parse_args()
|
| 381 |
+
|
| 382 |
+
torch.manual_seed(args.seed)
|
| 383 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 384 |
+
tokenizer = BpeTextTokenizer.from_file(args.tokenizer_path)
|
| 385 |
+
ckpt = torch.load(args.checkpoint, map_location="cpu")
|
| 386 |
+
model = build_model_from_ckpt(ckpt, tokenizer.vocab_size, args.max_len, device)
|
| 387 |
+
model.eval()
|
| 388 |
+
|
| 389 |
+
prompts = args.prompts.split("|")
|
| 390 |
+
# Keep the first empty prompt: it is unconditional generation.
|
| 391 |
+
print(f"[info] device={device} prompts={prompts} restarts={args.restarts} steps={args.steps}")
|
| 392 |
+
print(f"[info] checkpoint={args.checkpoint}")
|
| 393 |
+
|
| 394 |
+
out_path = Path(args.output)
|
| 395 |
+
out_path.parent.mkdir(parents=True, exist_ok=True)
|
| 396 |
+
configs = default_configs(args.steps, args.config_set)
|
| 397 |
+
for cfg in configs:
|
| 398 |
+
cfg.model_t_mode = args.model_t_mode
|
| 399 |
+
with out_path.open("w") as f:
|
| 400 |
+
for cfg in configs:
|
| 401 |
+
init, attn, lock, lock_probs, expanded = build_initial_state(
|
| 402 |
+
tokenizer=tokenizer,
|
| 403 |
+
prompts=prompts,
|
| 404 |
+
restarts=args.restarts,
|
| 405 |
+
max_len=args.max_len,
|
| 406 |
+
target_prob=args.target_prob,
|
| 407 |
+
eps=args.eps,
|
| 408 |
+
noise_init=args.noise_init,
|
| 409 |
+
noise_sigma=args.noise_sigma,
|
| 410 |
+
dirichlet_init_concentration=args.dirichlet_init_concentration,
|
| 411 |
+
device=device,
|
| 412 |
+
)
|
| 413 |
+
if args.decode_batch_size > 0 and init.size(0) > args.decode_batch_size:
|
| 414 |
+
decoded_parts = []
|
| 415 |
+
for start in range(0, init.size(0), args.decode_batch_size):
|
| 416 |
+
end = min(start + args.decode_batch_size, init.size(0))
|
| 417 |
+
part = decode_batch(
|
| 418 |
+
model,
|
| 419 |
+
init[start:end],
|
| 420 |
+
attn[start:end],
|
| 421 |
+
lock[start:end],
|
| 422 |
+
lock_probs[start:end],
|
| 423 |
+
cfg,
|
| 424 |
+
args.eps,
|
| 425 |
+
tokenizer.eos_id,
|
| 426 |
+
)
|
| 427 |
+
decoded_parts.append(part.detach().cpu())
|
| 428 |
+
print(f"[chunk] {cfg.label} decoded {end}/{init.size(0)}", flush=True)
|
| 429 |
+
decoded = torch.cat(decoded_parts, dim=0)
|
| 430 |
+
else:
|
| 431 |
+
decoded = decode_batch(model, init, attn, lock, lock_probs, cfg, args.eps, tokenizer.eos_id)
|
| 432 |
+
ids = decoded.argmax(dim=-1).detach().cpu().tolist()
|
| 433 |
+
texts = [decode_text(tokenizer, row) for row in ids]
|
| 434 |
+
rows = []
|
| 435 |
+
for i, text in enumerate(texts):
|
| 436 |
+
m = text_metrics(text)
|
| 437 |
+
m.update({"candidate": i, "prompt": expanded[i], "text": text})
|
| 438 |
+
rows.append(m)
|
| 439 |
+
if args.score_repeats > 0:
|
| 440 |
+
decoded_for_score = decoded.to(device) if decoded.device != device else decoded
|
| 441 |
+
pl = pseudo_likelihood_scores(
|
| 442 |
+
model,
|
| 443 |
+
tokenizer,
|
| 444 |
+
decoded_for_score,
|
| 445 |
+
attn,
|
| 446 |
+
lock,
|
| 447 |
+
args.target_prob,
|
| 448 |
+
args.eps,
|
| 449 |
+
repeats=args.score_repeats,
|
| 450 |
+
mask_frac=args.score_mask_frac,
|
| 451 |
+
rerank_t=args.rerank_t,
|
| 452 |
+
).detach().cpu().tolist()
|
| 453 |
+
for row, score in zip(rows, pl):
|
| 454 |
+
row["pseudo_logp"] = float(score)
|
| 455 |
+
row["rank_score"] = float(row["quality"] + args.pl_weight * score)
|
| 456 |
+
else:
|
| 457 |
+
for row in rows:
|
| 458 |
+
row["pseudo_logp"] = None
|
| 459 |
+
row["rank_score"] = float(row["quality"])
|
| 460 |
+
|
| 461 |
+
summary = {"type": "summary", "config": asdict(cfg), "agg": aggregate(rows)}
|
| 462 |
+
f.write(json.dumps(summary, ensure_ascii=False) + "\n")
|
| 463 |
+
print("\n" + "=" * 96)
|
| 464 |
+
print("[config]", cfg.label, asdict(cfg))
|
| 465 |
+
print("[metrics]", json.dumps(summary["agg"], ensure_ascii=False))
|
| 466 |
+
for prompt in prompts:
|
| 467 |
+
subset = [r for r in rows if r["prompt"] == prompt]
|
| 468 |
+
subset.sort(key=lambda r: r["rank_score"], reverse=True)
|
| 469 |
+
for rank, row in enumerate(subset[: args.topk], 1):
|
| 470 |
+
rec = {"type": "sample", "config": asdict(cfg), "rank": rank, **row}
|
| 471 |
+
f.write(json.dumps(rec, ensure_ascii=False) + "\n")
|
| 472 |
+
if rank <= 1:
|
| 473 |
+
print(f"\n--- best prompt={prompt!r} rank_score={row['rank_score']:.4f} quality={row['quality']:.4f} ---")
|
| 474 |
+
print(row["text"])
|
| 475 |
+
|
| 476 |
+
del init, attn, lock, lock_probs, decoded
|
| 477 |
+
if torch.cuda.is_available():
|
| 478 |
+
torch.cuda.empty_cache()
|
| 479 |
+
|
| 480 |
+
print(f"[done] wrote {out_path}")
|
| 481 |
+
|
| 482 |
+
|
| 483 |
+
if __name__ == "__main__":
|
| 484 |
+
main()
|
LTA_openwebtext_dualt/scripts/eval_lm1b_linear_simplex_genppl.py
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Algebraic simplex-linear GenPPL eval for endpoint models.
|
| 3 |
+
|
| 4 |
+
This decoder matches the supervised bridge:
|
| 5 |
+
|
| 6 |
+
p_t = (1 - t) * p0 + t * x1
|
| 7 |
+
|
| 8 |
+
Inference keeps the sampled p0 fixed and replaces the unknown x1 with the
|
| 9 |
+
model's current endpoint prediction:
|
| 10 |
+
|
| 11 |
+
p_{t_next} = (1 - t_next) * p0 + t_next * a_theta(p_t, t).
|
| 12 |
+
|
| 13 |
+
There is no Dirichlet/Gamma resampling in the loop.
|
| 14 |
+
"""
|
| 15 |
+
|
| 16 |
+
from __future__ import annotations
|
| 17 |
+
|
| 18 |
+
import argparse
|
| 19 |
+
import json
|
| 20 |
+
import math
|
| 21 |
+
import sys
|
| 22 |
+
from pathlib import Path
|
| 23 |
+
|
| 24 |
+
import torch
|
| 25 |
+
import torch.nn.functional as F
|
| 26 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 27 |
+
|
| 28 |
+
REPO_ROOT = Path(__file__).resolve().parents[1]
|
| 29 |
+
if str(REPO_ROOT) not in sys.path:
|
| 30 |
+
sys.path.insert(0, str(REPO_ROOT))
|
| 31 |
+
|
| 32 |
+
from flowtext_lab.decode import sample_noise_simplex, state_for_model
|
| 33 |
+
from flowtext_lab.genppl import filter_generated_texts, summarize_token_diversity
|
| 34 |
+
from flowtext_lab.tokenization import BpeTextTokenizer
|
| 35 |
+
|
| 36 |
+
from eval_lm1b_c1024_fullycoupled_sde_genppl import (
|
| 37 |
+
build_model,
|
| 38 |
+
collect_special_token_ids,
|
| 39 |
+
filter_endpoint_probs,
|
| 40 |
+
score_with_gpt2,
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def lerp(a: float, b: float, t: float) -> float:
|
| 45 |
+
return float(a) + float(t) * (float(b) - float(a))
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def project_endpoint(
|
| 49 |
+
logits: torch.Tensor,
|
| 50 |
+
*,
|
| 51 |
+
temp: float,
|
| 52 |
+
projection: str,
|
| 53 |
+
top_k: int,
|
| 54 |
+
top_p: float,
|
| 55 |
+
banned_ids: list[int],
|
| 56 |
+
gumbel_tau: float,
|
| 57 |
+
gumbel_noise_scale: float,
|
| 58 |
+
eps: float,
|
| 59 |
+
) -> torch.Tensor:
|
| 60 |
+
endpoint = F.softmax(logits / max(float(temp), eps), dim=-1)
|
| 61 |
+
endpoint = filter_endpoint_probs(
|
| 62 |
+
endpoint,
|
| 63 |
+
top_k=top_k,
|
| 64 |
+
top_p=top_p,
|
| 65 |
+
banned_ids=banned_ids,
|
| 66 |
+
eps=eps,
|
| 67 |
+
)
|
| 68 |
+
if projection == "soft":
|
| 69 |
+
return endpoint
|
| 70 |
+
if projection == "argmax":
|
| 71 |
+
ids = endpoint.argmax(dim=-1)
|
| 72 |
+
return torch.zeros_like(endpoint).scatter_(-1, ids.unsqueeze(-1), 1.0)
|
| 73 |
+
if projection == "sample":
|
| 74 |
+
ids = torch.multinomial(endpoint.reshape(-1, endpoint.size(-1)), 1).view(*endpoint.shape[:-1])
|
| 75 |
+
return torch.zeros_like(endpoint).scatter_(-1, ids.unsqueeze(-1), 1.0)
|
| 76 |
+
if projection == "gumbel_softmax":
|
| 77 |
+
u = torch.rand_like(endpoint).clamp_(min=eps, max=1.0 - eps)
|
| 78 |
+
g = -torch.log(-torch.log(u))
|
| 79 |
+
z = (endpoint.clamp_min(eps).log() + float(gumbel_noise_scale) * g) / max(float(gumbel_tau), eps)
|
| 80 |
+
y = F.softmax(z, dim=-1).clamp_min(eps)
|
| 81 |
+
return y / y.sum(dim=-1, keepdim=True).clamp_min(eps)
|
| 82 |
+
raise ValueError(f"unknown endpoint_projection: {projection}")
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
@torch.inference_mode()
|
| 86 |
+
def decode_linear_simplex(
|
| 87 |
+
model,
|
| 88 |
+
tokenizer: BpeTextTokenizer,
|
| 89 |
+
*,
|
| 90 |
+
n_samples: int,
|
| 91 |
+
batch_size: int,
|
| 92 |
+
max_len: int,
|
| 93 |
+
steps: int,
|
| 94 |
+
seed: int,
|
| 95 |
+
device: torch.device,
|
| 96 |
+
noise_init: str,
|
| 97 |
+
noise_sigma: float,
|
| 98 |
+
noise_dirichlet_concentration: float,
|
| 99 |
+
endpoint_temp_start: float,
|
| 100 |
+
endpoint_temp_end: float,
|
| 101 |
+
endpoint_projection: str,
|
| 102 |
+
endpoint_top_k: int,
|
| 103 |
+
endpoint_top_p: float,
|
| 104 |
+
ban_special_tokens: bool,
|
| 105 |
+
gumbel_tau_start: float,
|
| 106 |
+
gumbel_tau_end: float,
|
| 107 |
+
gumbel_noise_scale_start: float,
|
| 108 |
+
gumbel_noise_scale_end: float,
|
| 109 |
+
final_from: str,
|
| 110 |
+
) -> tuple[list[list[int]], list[str], dict]:
|
| 111 |
+
torch.manual_seed(seed)
|
| 112 |
+
eps = 1e-8
|
| 113 |
+
all_ids: list[list[int]] = []
|
| 114 |
+
all_texts: list[str] = []
|
| 115 |
+
remaining = n_samples
|
| 116 |
+
banned_endpoint_ids = collect_special_token_ids(tokenizer) if ban_special_tokens else []
|
| 117 |
+
|
| 118 |
+
while remaining > 0:
|
| 119 |
+
bs = min(batch_size, remaining)
|
| 120 |
+
p0 = sample_noise_simplex(
|
| 121 |
+
(bs, max_len),
|
| 122 |
+
tokenizer.vocab_size,
|
| 123 |
+
device,
|
| 124 |
+
eps,
|
| 125 |
+
noise_mode=noise_init,
|
| 126 |
+
target_prob=1.0,
|
| 127 |
+
noise_sigma=noise_sigma,
|
| 128 |
+
dirichlet_concentration=noise_dirichlet_concentration,
|
| 129 |
+
)
|
| 130 |
+
probs = p0.clone()
|
| 131 |
+
attn = torch.ones((bs, max_len), dtype=torch.bool, device=device)
|
| 132 |
+
last_endpoint = probs
|
| 133 |
+
|
| 134 |
+
for step in range(steps):
|
| 135 |
+
cur_t = step / max(steps, 1)
|
| 136 |
+
next_t = (step + 1) / max(steps, 1)
|
| 137 |
+
t = torch.full((bs,), float(cur_t), dtype=torch.float32, device=device)
|
| 138 |
+
logits = model(state_for_model(model, probs, eps), t, attn).float()
|
| 139 |
+
|
| 140 |
+
endpoint = project_endpoint(
|
| 141 |
+
logits,
|
| 142 |
+
temp=lerp(endpoint_temp_start, endpoint_temp_end, cur_t),
|
| 143 |
+
projection=endpoint_projection,
|
| 144 |
+
top_k=endpoint_top_k,
|
| 145 |
+
top_p=endpoint_top_p,
|
| 146 |
+
banned_ids=banned_endpoint_ids,
|
| 147 |
+
gumbel_tau=lerp(gumbel_tau_start, gumbel_tau_end, cur_t),
|
| 148 |
+
gumbel_noise_scale=lerp(gumbel_noise_scale_start, gumbel_noise_scale_end, cur_t),
|
| 149 |
+
eps=eps,
|
| 150 |
+
)
|
| 151 |
+
last_endpoint = endpoint
|
| 152 |
+
probs = (1.0 - next_t) * p0 + next_t * endpoint
|
| 153 |
+
probs = probs.clamp_min(eps)
|
| 154 |
+
probs = probs / probs.sum(dim=-1, keepdim=True).clamp_min(eps)
|
| 155 |
+
|
| 156 |
+
if final_from == "blend_0.5":
|
| 157 |
+
final_probs = 0.5 * probs + 0.5 * last_endpoint
|
| 158 |
+
ids = final_probs.argmax(dim=-1).detach().cpu().tolist()
|
| 159 |
+
elif final_from == "model_t1":
|
| 160 |
+
t = torch.ones((bs,), dtype=torch.float32, device=device)
|
| 161 |
+
final_logits = model(state_for_model(model, probs, eps), t, attn).float()
|
| 162 |
+
ids = final_logits.argmax(dim=-1).detach().cpu().tolist()
|
| 163 |
+
else:
|
| 164 |
+
raise ValueError(f"unknown final_from: {final_from}")
|
| 165 |
+
|
| 166 |
+
all_ids.extend(ids)
|
| 167 |
+
all_texts.extend(tokenizer.decode(row, stop_at_eos=False, skip_special_tokens=False) for row in ids)
|
| 168 |
+
remaining -= bs
|
| 169 |
+
print(f"[linear] generated {n_samples - remaining}/{n_samples}", flush=True)
|
| 170 |
+
|
| 171 |
+
cfg = {
|
| 172 |
+
"decode_rule": "linear_simplex_algebraic",
|
| 173 |
+
"steps": steps,
|
| 174 |
+
"noise_init": noise_init,
|
| 175 |
+
"noise_sigma": noise_sigma,
|
| 176 |
+
"noise_dirichlet_concentration": noise_dirichlet_concentration,
|
| 177 |
+
"endpoint_temp_start": endpoint_temp_start,
|
| 178 |
+
"endpoint_temp_end": endpoint_temp_end,
|
| 179 |
+
"endpoint_projection": endpoint_projection,
|
| 180 |
+
"endpoint_top_k": endpoint_top_k,
|
| 181 |
+
"endpoint_top_p": endpoint_top_p,
|
| 182 |
+
"ban_special_tokens": ban_special_tokens,
|
| 183 |
+
"banned_endpoint_ids": banned_endpoint_ids,
|
| 184 |
+
"gumbel_tau_start": gumbel_tau_start,
|
| 185 |
+
"gumbel_tau_end": gumbel_tau_end,
|
| 186 |
+
"gumbel_noise_scale_start": gumbel_noise_scale_start,
|
| 187 |
+
"gumbel_noise_scale_end": gumbel_noise_scale_end,
|
| 188 |
+
"final_from": final_from,
|
| 189 |
+
"n_samples": n_samples,
|
| 190 |
+
"seed": seed,
|
| 191 |
+
}
|
| 192 |
+
return all_ids, all_texts, cfg
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
def parse_args() -> argparse.Namespace:
|
| 196 |
+
p = argparse.ArgumentParser(description="Linear-simplex algebraic GenPPL eval")
|
| 197 |
+
p.add_argument("--checkpoint", required=True)
|
| 198 |
+
p.add_argument("--tokenizer_path", required=True)
|
| 199 |
+
p.add_argument("--scorer", required=True)
|
| 200 |
+
p.add_argument("--out_dir", required=True)
|
| 201 |
+
p.add_argument("--n_samples", type=int, default=128)
|
| 202 |
+
p.add_argument("--max_len", type=int, default=128)
|
| 203 |
+
p.add_argument("--steps", type=int, default=128)
|
| 204 |
+
p.add_argument("--batch_size", type=int, default=16)
|
| 205 |
+
p.add_argument("--score_batch", type=int, default=8)
|
| 206 |
+
p.add_argument("--score_max_length", type=int, default=1024)
|
| 207 |
+
p.add_argument("--noise_init", choices=["uniform", "logistic_normal", "dirichlet"], default="logistic_normal")
|
| 208 |
+
p.add_argument("--noise_sigma", type=float, default=3.0)
|
| 209 |
+
p.add_argument("--noise_dirichlet_concentration", type=float, default=1.0)
|
| 210 |
+
p.add_argument("--endpoint_temp_start", type=float, default=1.45)
|
| 211 |
+
p.add_argument("--endpoint_temp_end", type=float, default=0.8)
|
| 212 |
+
p.add_argument("--endpoint_projection", choices=["soft", "sample", "argmax", "gumbel_softmax"], default="soft")
|
| 213 |
+
p.add_argument("--endpoint_top_k", type=int, default=0)
|
| 214 |
+
p.add_argument("--endpoint_top_p", type=float, default=1.0)
|
| 215 |
+
p.add_argument("--ban_special_tokens", action="store_true")
|
| 216 |
+
p.add_argument("--gumbel_tau_start", type=float, default=1.0)
|
| 217 |
+
p.add_argument("--gumbel_tau_end", type=float, default=0.2)
|
| 218 |
+
p.add_argument("--gumbel_noise_scale_start", type=float, default=1.0)
|
| 219 |
+
p.add_argument("--gumbel_noise_scale_end", type=float, default=0.0)
|
| 220 |
+
p.add_argument("--final_from", choices=["blend_0.5", "model_t1"], default="model_t1")
|
| 221 |
+
p.add_argument("--seed", type=int, default=20260524)
|
| 222 |
+
return p.parse_args()
|
| 223 |
+
|
| 224 |
+
|
| 225 |
+
@torch.no_grad()
|
| 226 |
+
def main() -> None:
|
| 227 |
+
args = parse_args()
|
| 228 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 229 |
+
print(f"[load] {args.checkpoint}", flush=True)
|
| 230 |
+
ckpt = torch.load(args.checkpoint, map_location="cpu", weights_only=False)
|
| 231 |
+
step = ckpt.get("step")
|
| 232 |
+
print(f"[ckpt] step={step}", flush=True)
|
| 233 |
+
|
| 234 |
+
tokenizer = BpeTextTokenizer.from_file(args.tokenizer_path)
|
| 235 |
+
model = build_model(ckpt, tokenizer, device)
|
| 236 |
+
ids, texts, decode_cfg = decode_linear_simplex(
|
| 237 |
+
model,
|
| 238 |
+
tokenizer,
|
| 239 |
+
n_samples=args.n_samples,
|
| 240 |
+
batch_size=args.batch_size,
|
| 241 |
+
max_len=args.max_len,
|
| 242 |
+
steps=args.steps,
|
| 243 |
+
seed=args.seed,
|
| 244 |
+
device=device,
|
| 245 |
+
noise_init=args.noise_init,
|
| 246 |
+
noise_sigma=args.noise_sigma,
|
| 247 |
+
noise_dirichlet_concentration=args.noise_dirichlet_concentration,
|
| 248 |
+
endpoint_temp_start=args.endpoint_temp_start,
|
| 249 |
+
endpoint_temp_end=args.endpoint_temp_end,
|
| 250 |
+
endpoint_projection=args.endpoint_projection,
|
| 251 |
+
endpoint_top_k=args.endpoint_top_k,
|
| 252 |
+
endpoint_top_p=args.endpoint_top_p,
|
| 253 |
+
ban_special_tokens=args.ban_special_tokens,
|
| 254 |
+
gumbel_tau_start=args.gumbel_tau_start,
|
| 255 |
+
gumbel_tau_end=args.gumbel_tau_end,
|
| 256 |
+
gumbel_noise_scale_start=args.gumbel_noise_scale_start,
|
| 257 |
+
gumbel_noise_scale_end=args.gumbel_noise_scale_end,
|
| 258 |
+
final_from=args.final_from,
|
| 259 |
+
)
|
| 260 |
+
del model
|
| 261 |
+
if torch.cuda.is_available():
|
| 262 |
+
torch.cuda.empty_cache()
|
| 263 |
+
|
| 264 |
+
def strip_special(t: str) -> str:
|
| 265 |
+
import re
|
| 266 |
+
t = t.replace("[CLS]", " ").replace("[SEP]", " ").replace("[PAD]", " ")
|
| 267 |
+
t = t.replace("<|endoftext|>", " ")
|
| 268 |
+
return re.sub(r"\s+", " ", t).strip()
|
| 269 |
+
|
| 270 |
+
stripped = [strip_special(t) for t in texts]
|
| 271 |
+
kept_raw, _ = filter_generated_texts(texts, min_chars=1, normalize_whitespace=False, drop_empty=True)
|
| 272 |
+
kept_stripped, _ = filter_generated_texts(stripped, min_chars=1, normalize_whitespace=True, drop_empty=True)
|
| 273 |
+
diversity = summarize_token_diversity(ids).__dict__
|
| 274 |
+
|
| 275 |
+
print(f"[score] loading scorer: {args.scorer}", flush=True)
|
| 276 |
+
scorer_tok = AutoTokenizer.from_pretrained(args.scorer)
|
| 277 |
+
if scorer_tok.pad_token_id is None:
|
| 278 |
+
scorer_tok.pad_token = scorer_tok.eos_token
|
| 279 |
+
scorer_tok.pad_token_id = scorer_tok.eos_token_id
|
| 280 |
+
scorer = AutoModelForCausalLM.from_pretrained(args.scorer).to(device).eval()
|
| 281 |
+
if getattr(scorer.config, "pad_token_id", None) is None:
|
| 282 |
+
scorer.config.pad_token_id = scorer_tok.pad_token_id
|
| 283 |
+
|
| 284 |
+
raw_ppl = score_with_gpt2(
|
| 285 |
+
kept_raw, scorer, scorer_tok,
|
| 286 |
+
batch_size=args.score_batch, max_length=args.score_max_length, device=device,
|
| 287 |
+
)
|
| 288 |
+
stripped_ppl = score_with_gpt2(
|
| 289 |
+
kept_stripped, scorer, scorer_tok,
|
| 290 |
+
batch_size=args.score_batch, max_length=args.score_max_length, device=device,
|
| 291 |
+
)
|
| 292 |
+
summary = {
|
| 293 |
+
"type": "summary",
|
| 294 |
+
"checkpoint": args.checkpoint,
|
| 295 |
+
"step": step,
|
| 296 |
+
"decode": decode_cfg,
|
| 297 |
+
"raw_genppl": raw_ppl,
|
| 298 |
+
"stripped_genppl": stripped_ppl,
|
| 299 |
+
"diversity": diversity,
|
| 300 |
+
}
|
| 301 |
+
|
| 302 |
+
out_dir = Path(args.out_dir)
|
| 303 |
+
out_dir.mkdir(parents=True, exist_ok=True)
|
| 304 |
+
out_jsonl = out_dir / f"linear_steps{args.steps}_samples{args.n_samples}_scored.jsonl"
|
| 305 |
+
with out_jsonl.open("w", encoding="utf-8") as f:
|
| 306 |
+
f.write(json.dumps(summary, ensure_ascii=False) + "\n")
|
| 307 |
+
for i, (raw, clean) in enumerate(zip(texts, stripped)):
|
| 308 |
+
f.write(json.dumps({"type": "sample", "index": i, "raw_text": raw, "stripped_text": clean}, ensure_ascii=False) + "\n")
|
| 309 |
+
print("[summary]", json.dumps(summary, ensure_ascii=False, indent=2), flush=True)
|
| 310 |
+
print(f"[done] {out_jsonl}", flush=True)
|
| 311 |
+
|
| 312 |
+
|
| 313 |
+
if __name__ == "__main__":
|
| 314 |
+
main()
|
LTA_openwebtext_dualt/scripts/eval_train8_overfit_sweep.sh
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
|
| 6 |
+
STAMP="${STAMP:?set STAMP used by run_train8_overfit_sweep_4gpu.sh}"
|
| 7 |
+
TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-standard/tokenizer.json}"
|
| 8 |
+
CACHE_DIR="${CACHE_DIR:-/e2e-data/evad-tech-vla/wanghan58/data/small_benchmarks/langflow_2604_11748/openwebtext_lta_cached_chunks/gpt2_len1024_train8_overfit}"
|
| 9 |
+
OUT_ROOT="${OUT_ROOT:-docs/lta_samples/metrics_20260517/train8_overfit_${STAMP}}"
|
| 10 |
+
export OUT_ROOT
|
| 11 |
+
mkdir -p "${OUT_ROOT}"
|
| 12 |
+
|
| 13 |
+
for run in \
|
| 14 |
+
"train8_n1024_hard_ce_onehot_${STAMP}" \
|
| 15 |
+
"train8_n1024_hard_ce_bridge_${STAMP}" \
|
| 16 |
+
"train8_n1024_linear_soft_kl_onehot_${STAMP}" \
|
| 17 |
+
"train8_n1024_linear_soft_kl_bridge_${STAMP}"
|
| 18 |
+
do
|
| 19 |
+
echo "[eval-overfit] ${run}"
|
| 20 |
+
python scripts/eval_train8_overfit_ckpts.py \
|
| 21 |
+
--run_dir "runs/${run}" \
|
| 22 |
+
--cache_dir "${CACHE_DIR}" \
|
| 23 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 24 |
+
--out_dir "${OUT_ROOT}/${run}" \
|
| 25 |
+
--max_len 1024 \
|
| 26 |
+
--limit 8 \
|
| 27 |
+
--t_values 0.125,0.25,0.5,0.75,1.0 \
|
| 28 |
+
--seeds 123,456,789
|
| 29 |
+
done
|
| 30 |
+
|
| 31 |
+
python - <<'PY'
|
| 32 |
+
import json
|
| 33 |
+
import os
|
| 34 |
+
from pathlib import Path
|
| 35 |
+
root = Path(os.environ["OUT_ROOT"])
|
| 36 |
+
rows = []
|
| 37 |
+
for p in sorted(root.glob("*/result.json")):
|
| 38 |
+
r = json.loads(p.read_text())
|
| 39 |
+
last = r["last"]
|
| 40 |
+
rows.append({
|
| 41 |
+
"run": p.parent.name,
|
| 42 |
+
"first_fit_step": r["first_fit_step"],
|
| 43 |
+
"best_acc": r["best_acc"],
|
| 44 |
+
"best_objective": r["best_objective"],
|
| 45 |
+
"last_acc": last["gold_acc_mean"],
|
| 46 |
+
"last_objective": last["objective_mean"],
|
| 47 |
+
"last_ce": last["gold_ce_mean"],
|
| 48 |
+
})
|
| 49 |
+
with (root / "combined.tsv").open("w") as f:
|
| 50 |
+
f.write("run\tfirst_fit_step\tbest_acc\tbest_objective\tlast_acc\tlast_objective\tlast_ce\n")
|
| 51 |
+
for r in rows:
|
| 52 |
+
f.write("\t".join(str(r[k]) for k in ["run","first_fit_step","best_acc","best_objective","last_acc","last_objective","last_ce"]) + "\n")
|
| 53 |
+
print(root / "combined.tsv")
|
| 54 |
+
PY
|
LTA_openwebtext_dualt/scripts/launch_ar_openwebtext_duo_small_8gpu_1m.sh
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 6 |
+
export TOKENIZERS_PARALLELISM=false
|
| 7 |
+
export PYTHONUNBUFFERED=1
|
| 8 |
+
export NCCL_DEBUG="${NCCL_DEBUG:-WARN}"
|
| 9 |
+
export TORCH_DISTRIBUTED_TIMEOUT="${TORCH_DISTRIBUTED_TIMEOUT:-3600}"
|
| 10 |
+
|
| 11 |
+
RUN_NAME="${RUN_NAME:-ar_owt_flmpack_gpt2_small_len1024_gbs512_8gpu_1m}"
|
| 12 |
+
DATA_PATH="${DATA_PATH:-/e2e-data/evad-tech-vla/wanghan58/data/small_benchmarks/langflow_2604_11748/openwebtext}"
|
| 13 |
+
TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-standard/tokenizer.json}"
|
| 14 |
+
TEXT_COLUMN="${TEXT_COLUMN:-text}"
|
| 15 |
+
OPENWEBTEXT_SPLIT="${OPENWEBTEXT_SPLIT:-train_minus_100k}"
|
| 16 |
+
SAVE_DIR="${SAVE_DIR:-runs/${RUN_NAME}}"
|
| 17 |
+
LOG_FILE="${LOG_FILE:-logs/${RUN_NAME}.log}"
|
| 18 |
+
|
| 19 |
+
NNODES="${NNODES:-1}"
|
| 20 |
+
NPROC_PER_NODE="${NPROC_PER_NODE:-8}"
|
| 21 |
+
NODE_RANK="${NODE_RANK:-0}"
|
| 22 |
+
MASTER_ADDR="${MASTER_ADDR:-127.0.0.1}"
|
| 23 |
+
MASTER_PORT="${MASTER_PORT:-29643}"
|
| 24 |
+
|
| 25 |
+
GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 26 |
+
PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-32}"
|
| 27 |
+
TOTAL_STEPS="${TOTAL_STEPS:-1000000}"
|
| 28 |
+
WARMUP_STEPS="${WARMUP_STEPS:-2500}"
|
| 29 |
+
MAX_LEN="${MAX_LEN:-1024}"
|
| 30 |
+
NUM_WORKERS="${NUM_WORKERS:-4}"
|
| 31 |
+
LOG_EVERY="${LOG_EVERY:-100}"
|
| 32 |
+
SAVE_EVERY="${SAVE_EVERY:-20000}"
|
| 33 |
+
LATEST_EVERY="${LATEST_EVERY:-1000}"
|
| 34 |
+
SAMPLE_EVERY="${SAMPLE_EVERY:-0}"
|
| 35 |
+
RESUME_PATH="${RESUME_PATH:-}"
|
| 36 |
+
ALLOW_EXISTING_SAVE_DIR="${ALLOW_EXISTING_SAVE_DIR:-0}"
|
| 37 |
+
ENABLE_TORCH_COMPILE="${ENABLE_TORCH_COMPILE:-0}"
|
| 38 |
+
|
| 39 |
+
COMPILE_ARGS=()
|
| 40 |
+
if [[ "${ENABLE_TORCH_COMPILE}" == "1" ]]; then
|
| 41 |
+
COMPILE_ARGS+=(--torch_compile --compile_mode reduce-overhead)
|
| 42 |
+
fi
|
| 43 |
+
RESUME_ARGS=()
|
| 44 |
+
if [[ -n "${RESUME_PATH}" ]]; then
|
| 45 |
+
RESUME_ARGS+=(--resume_path "${RESUME_PATH}")
|
| 46 |
+
fi
|
| 47 |
+
TEXT_COLUMN_ARGS=()
|
| 48 |
+
if [[ -n "${TEXT_COLUMN}" ]]; then
|
| 49 |
+
TEXT_COLUMN_ARGS+=(--text_column "${TEXT_COLUMN}")
|
| 50 |
+
fi
|
| 51 |
+
|
| 52 |
+
if [[ -f "${SAVE_DIR}/args.json" && -z "${RESUME_PATH}" && "${ALLOW_EXISTING_SAVE_DIR}" != "1" ]]; then
|
| 53 |
+
echo "Refusing to start because SAVE_DIR already contains args.json: ${SAVE_DIR}" >&2
|
| 54 |
+
echo "Use a new RUN_NAME/SAVE_DIR, set RESUME_PATH to resume, or set ALLOW_EXISTING_SAVE_DIR=1 intentionally." >&2
|
| 55 |
+
exit 2
|
| 56 |
+
fi
|
| 57 |
+
|
| 58 |
+
mkdir -p logs runs "${SAVE_DIR}"
|
| 59 |
+
|
| 60 |
+
python -m torch.distributed.run \
|
| 61 |
+
--nnodes="${NNODES}" \
|
| 62 |
+
--nproc_per_node="${NPROC_PER_NODE}" \
|
| 63 |
+
--node_rank="${NODE_RANK}" \
|
| 64 |
+
--master_addr="${MASTER_ADDR}" \
|
| 65 |
+
--master_port="${MASTER_PORT}" \
|
| 66 |
+
train_ar.py \
|
| 67 |
+
--data_path "${DATA_PATH}" \
|
| 68 |
+
"${TEXT_COLUMN_ARGS[@]}" \
|
| 69 |
+
--openwebtext_split "${OPENWEBTEXT_SPLIT}" \
|
| 70 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 71 |
+
--save_dir "${SAVE_DIR}" \
|
| 72 |
+
--wrap \
|
| 73 |
+
--max_len "${MAX_LEN}" \
|
| 74 |
+
--batch_size "${PER_GPU_BATCH_SIZE}" \
|
| 75 |
+
--num_workers "${NUM_WORKERS}" \
|
| 76 |
+
--global_batch_size "${GLOBAL_BATCH_SIZE}" \
|
| 77 |
+
--total_steps "${TOTAL_STEPS}" \
|
| 78 |
+
--log_every "${LOG_EVERY}" \
|
| 79 |
+
--save_every "${SAVE_EVERY}" \
|
| 80 |
+
--latest_every "${LATEST_EVERY}" \
|
| 81 |
+
--sample_every "${SAMPLE_EVERY}" \
|
| 82 |
+
--lr 3e-4 \
|
| 83 |
+
--weight_decay 0 \
|
| 84 |
+
--adam_beta1 0.9 \
|
| 85 |
+
--adam_beta2 0.999 \
|
| 86 |
+
--adam_eps 1e-8 \
|
| 87 |
+
--warmup_steps "${WARMUP_STEPS}" \
|
| 88 |
+
--lr_schedule constant_warmup \
|
| 89 |
+
--grad_clip 1.0 \
|
| 90 |
+
--seed 123 \
|
| 91 |
+
--d_model 768 \
|
| 92 |
+
--n_layers 12 \
|
| 93 |
+
--n_heads 12 \
|
| 94 |
+
--dim_ff 3072 \
|
| 95 |
+
--dropout 0.1 \
|
| 96 |
+
--tie_embeddings \
|
| 97 |
+
"${RESUME_ARGS[@]}" \
|
| 98 |
+
"${COMPILE_ARGS[@]}" \
|
| 99 |
+
--bf16 2>&1 | tee -a "${LOG_FILE}"
|
LTA_openwebtext_dualt/scripts/launch_lm1b_flm_8gpu_repro_20260506.sh
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 6 |
+
export TOKENIZERS_PARALLELISM=false
|
| 7 |
+
export PYTHONUNBUFFERED=1
|
| 8 |
+
export NCCL_DEBUG="${NCCL_DEBUG:-WARN}"
|
| 9 |
+
export TORCH_DISTRIBUTED_TIMEOUT="${TORCH_DISTRIBUTED_TIMEOUT:-3600}"
|
| 10 |
+
export CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0,1,2,3,4,5,6,7}"
|
| 11 |
+
|
| 12 |
+
# Unified LM1B FLM baseline.
|
| 13 |
+
# This uses the same tokenizer/data/model/optimizer setup as MDLM/DUO.
|
| 14 |
+
|
| 15 |
+
RUN_TAG="${RUN_TAG:-20260506_repro}"
|
| 16 |
+
RUN_NAME="${RUN_NAME:-lm1b_flm_unified_ddit_small_len128_gbs512_8gpu_1m_${RUN_TAG}}"
|
| 17 |
+
DATA_PATH="${DATA_PATH:-data/lm1b_train_parquet}"
|
| 18 |
+
TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/workspace/imagenet_handoff_20260327/nlp_dts_light/assets/distilbert-base-uncased/tokenizer.json}"
|
| 19 |
+
TEXT_COLUMN="${TEXT_COLUMN:-}"
|
| 20 |
+
OPENWEBTEXT_SPLIT="${OPENWEBTEXT_SPLIT:-all}"
|
| 21 |
+
SAVE_DIR="${SAVE_DIR:-runs/${RUN_NAME}}"
|
| 22 |
+
LOG_FILE="${LOG_FILE:-logs/${RUN_NAME}.log}"
|
| 23 |
+
|
| 24 |
+
NNODES="${NNODES:-1}"
|
| 25 |
+
NPROC_PER_NODE="${NPROC_PER_NODE:-8}"
|
| 26 |
+
NODE_RANK="${NODE_RANK:-0}"
|
| 27 |
+
MASTER_ADDR="${MASTER_ADDR:-127.0.0.1}"
|
| 28 |
+
MASTER_PORT="${MASTER_PORT:-29646}"
|
| 29 |
+
|
| 30 |
+
GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 31 |
+
PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-64}"
|
| 32 |
+
TOTAL_STEPS="${TOTAL_STEPS:-1000000}"
|
| 33 |
+
WARMUP_STEPS="${WARMUP_STEPS:-2500}"
|
| 34 |
+
MAX_LEN="${MAX_LEN:-128}"
|
| 35 |
+
WRAP_MODE="${WRAP_MODE:-stream}"
|
| 36 |
+
WRAP_RECORD_BUFFER_SIZE="${WRAP_RECORD_BUFFER_SIZE:-200}"
|
| 37 |
+
NUM_WORKERS="${NUM_WORKERS:-0}"
|
| 38 |
+
LOG_EVERY="${LOG_EVERY:-100}"
|
| 39 |
+
SAVE_EVERY="${SAVE_EVERY:-20000}"
|
| 40 |
+
LATEST_EVERY="${LATEST_EVERY:-1000}"
|
| 41 |
+
RESUME_PATH="${RESUME_PATH:-}"
|
| 42 |
+
ALLOW_EXISTING_SAVE_DIR="${ALLOW_EXISTING_SAVE_DIR:-0}"
|
| 43 |
+
ENABLE_TORCH_COMPILE="${ENABLE_TORCH_COMPILE:-0}"
|
| 44 |
+
FORCE_DISABLE_TORCH_COMPILE="${FORCE_DISABLE_TORCH_COMPILE:-1}"
|
| 45 |
+
|
| 46 |
+
if [[ "${FORCE_DISABLE_TORCH_COMPILE}" == "1" ]]; then
|
| 47 |
+
ENABLE_TORCH_COMPILE=0
|
| 48 |
+
fi
|
| 49 |
+
if [[ "${DATA_PATH}" == *"lm1b_train_parquet"* && "${NUM_WORKERS}" != "0" ]]; then
|
| 50 |
+
echo "LM1B has only 9 parquet shards; forcing NUM_WORKERS=0 to avoid empty DDP dataloader shards." >&2
|
| 51 |
+
NUM_WORKERS=0
|
| 52 |
+
fi
|
| 53 |
+
|
| 54 |
+
COMPILE_ARGS=()
|
| 55 |
+
if [[ "${ENABLE_TORCH_COMPILE}" == "1" ]]; then
|
| 56 |
+
COMPILE_ARGS+=(--torch_compile --compile_mode reduce-overhead)
|
| 57 |
+
fi
|
| 58 |
+
RESUME_ARGS=()
|
| 59 |
+
if [[ -n "${RESUME_PATH}" ]]; then
|
| 60 |
+
RESUME_ARGS+=(--resume_path "${RESUME_PATH}")
|
| 61 |
+
fi
|
| 62 |
+
TEXT_COLUMN_ARGS=()
|
| 63 |
+
if [[ -n "${TEXT_COLUMN}" ]]; then
|
| 64 |
+
TEXT_COLUMN_ARGS+=(--text_column "${TEXT_COLUMN}")
|
| 65 |
+
fi
|
| 66 |
+
|
| 67 |
+
if [[ -f "${SAVE_DIR}/args.json" && -z "${RESUME_PATH}" && "${ALLOW_EXISTING_SAVE_DIR}" != "1" ]]; then
|
| 68 |
+
echo "Refusing to start because SAVE_DIR already contains args.json: ${SAVE_DIR}" >&2
|
| 69 |
+
echo "Use a new RUN_NAME/SAVE_DIR, set RESUME_PATH to resume, or set ALLOW_EXISTING_SAVE_DIR=1 intentionally." >&2
|
| 70 |
+
exit 2
|
| 71 |
+
fi
|
| 72 |
+
|
| 73 |
+
mkdir -p logs runs "${SAVE_DIR}"
|
| 74 |
+
echo "[launch] method=flm host=$(hostname) time=$(date -Iseconds)"
|
| 75 |
+
echo "[launch] cwd=$(pwd)"
|
| 76 |
+
echo "[launch] run_name=${RUN_NAME}"
|
| 77 |
+
echo "[launch] save_dir=${SAVE_DIR}"
|
| 78 |
+
echo "[launch] log_file=${LOG_FILE}"
|
| 79 |
+
echo "[launch] nproc_per_node=${NPROC_PER_NODE} global_batch_size=${GLOBAL_BATCH_SIZE} per_gpu_batch_size=${PER_GPU_BATCH_SIZE}"
|
| 80 |
+
|
| 81 |
+
python -m torch.distributed.run \
|
| 82 |
+
--nnodes="${NNODES}" \
|
| 83 |
+
--nproc_per_node="${NPROC_PER_NODE}" \
|
| 84 |
+
--node_rank="${NODE_RANK}" \
|
| 85 |
+
--master_addr="${MASTER_ADDR}" \
|
| 86 |
+
--master_port="${MASTER_PORT}" \
|
| 87 |
+
train_baseline.py \
|
| 88 |
+
--baseline_method flm \
|
| 89 |
+
--data_path "${DATA_PATH}" \
|
| 90 |
+
"${TEXT_COLUMN_ARGS[@]}" \
|
| 91 |
+
--openwebtext_split "${OPENWEBTEXT_SPLIT}" \
|
| 92 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 93 |
+
--save_dir "${SAVE_DIR}" \
|
| 94 |
+
--max_len "${MAX_LEN}" \
|
| 95 |
+
--batch_size "${PER_GPU_BATCH_SIZE}" \
|
| 96 |
+
--num_workers "${NUM_WORKERS}" \
|
| 97 |
+
--global_batch_size "${GLOBAL_BATCH_SIZE}" \
|
| 98 |
+
--wrap_mode "${WRAP_MODE}" \
|
| 99 |
+
--wrap_record_buffer_size "${WRAP_RECORD_BUFFER_SIZE}" \
|
| 100 |
+
--total_steps "${TOTAL_STEPS}" \
|
| 101 |
+
--log_every "${LOG_EVERY}" \
|
| 102 |
+
--save_every "${SAVE_EVERY}" \
|
| 103 |
+
--latest_every "${LATEST_EVERY}" \
|
| 104 |
+
--lr 3e-4 \
|
| 105 |
+
--weight_decay 0 \
|
| 106 |
+
--adam_beta1 0.9 \
|
| 107 |
+
--adam_beta2 0.999 \
|
| 108 |
+
--adam_eps 1e-8 \
|
| 109 |
+
--warmup_steps "${WARMUP_STEPS}" \
|
| 110 |
+
--lr_schedule constant_warmup \
|
| 111 |
+
--grad_clip 1.0 \
|
| 112 |
+
--seed 123 \
|
| 113 |
+
--d_model 768 \
|
| 114 |
+
--cond_dim 128 \
|
| 115 |
+
--n_layers 12 \
|
| 116 |
+
--n_heads 12 \
|
| 117 |
+
--dim_ff 3072 \
|
| 118 |
+
--dropout 0.1 \
|
| 119 |
+
--model_type ddit \
|
| 120 |
+
--sampling_eps 1e-3 \
|
| 121 |
+
"${RESUME_ARGS[@]}" \
|
| 122 |
+
"${COMPILE_ARGS[@]}" \
|
| 123 |
+
--bf16 2>&1 | tee -a "${LOG_FILE}"
|
LTA_openwebtext_dualt/scripts/launch_lta_lm1b_categorical_fullvocab_c1024_gaussian_linear_mean_fullycoupled_8gpu_small_1m.sh
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 6 |
+
export TOKENIZERS_PARALLELISM=false
|
| 7 |
+
export PYTHONUNBUFFERED=1
|
| 8 |
+
export NCCL_DEBUG="${NCCL_DEBUG:-WARN}"
|
| 9 |
+
export TORCH_DISTRIBUTED_TIMEOUT="${TORCH_DISTRIBUTED_TIMEOUT:-3600}"
|
| 10 |
+
|
| 11 |
+
# Gaussian/logistic-normal center-mixture with probability-linear mean:
|
| 12 |
+
# model_t == support t == semantic endpoint t
|
| 13 |
+
# endpoint is categorical full-vocab, state is logistic-normal around
|
| 14 |
+
# mu_c(t) = (1 - t) uniform + t onehot(center)
|
| 15 |
+
RUN_NAME="${RUN_NAME:-lta_lm1b_logisticnormal_linearmean_categorical_fullvocab_c1024_fullycoupled_flmpack_onehot_hardce_ddit_small_len128_gbs512_8gpu_1m_nw0}"
|
| 16 |
+
DATA_PATH="${DATA_PATH:-data/lm1b_train_parquet}"
|
| 17 |
+
TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/workspace/imagenet_handoff_20260327/nlp_dts_light/assets/distilbert-base-uncased/tokenizer.json}"
|
| 18 |
+
TEXT_COLUMN="${TEXT_COLUMN:-}"
|
| 19 |
+
OPENWEBTEXT_SPLIT="${OPENWEBTEXT_SPLIT:-all}"
|
| 20 |
+
SAVE_DIR="${SAVE_DIR:-runs/${RUN_NAME}}"
|
| 21 |
+
LOG_FILE="${LOG_FILE:-logs/${RUN_NAME}.log}"
|
| 22 |
+
|
| 23 |
+
NNODES="${NNODES:-1}"
|
| 24 |
+
NPROC_PER_NODE="${NPROC_PER_NODE:-8}"
|
| 25 |
+
NODE_RANK="${NODE_RANK:-0}"
|
| 26 |
+
MASTER_ADDR="${MASTER_ADDR:-127.0.0.1}"
|
| 27 |
+
MASTER_PORT="${MASTER_PORT:-29631}"
|
| 28 |
+
|
| 29 |
+
GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 30 |
+
PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-64}"
|
| 31 |
+
TOTAL_STEPS="${TOTAL_STEPS:-1000000}"
|
| 32 |
+
WARMUP_STEPS="${WARMUP_STEPS:-2500}"
|
| 33 |
+
MAX_LEN="${MAX_LEN:-128}"
|
| 34 |
+
WRAP_MODE="${WRAP_MODE:-stream}"
|
| 35 |
+
WRAP_RECORD_BUFFER_SIZE="${WRAP_RECORD_BUFFER_SIZE:-200}"
|
| 36 |
+
NUM_WORKERS="${NUM_WORKERS:-0}"
|
| 37 |
+
LOG_EVERY="${LOG_EVERY:-100}"
|
| 38 |
+
SAVE_EVERY="${SAVE_EVERY:-20000}"
|
| 39 |
+
LATEST_EVERY="${LATEST_EVERY:-1000}"
|
| 40 |
+
EVAL_EVERY="${EVAL_EVERY:-0}"
|
| 41 |
+
RESUME_PATH="${RESUME_PATH:-}"
|
| 42 |
+
ALLOW_EXISTING_SAVE_DIR="${ALLOW_EXISTING_SAVE_DIR:-0}"
|
| 43 |
+
ENABLE_TORCH_COMPILE="${ENABLE_TORCH_COMPILE:-0}"
|
| 44 |
+
FORCE_DISABLE_TORCH_COMPILE="${FORCE_DISABLE_TORCH_COMPILE:-1}"
|
| 45 |
+
|
| 46 |
+
if [[ "${FORCE_DISABLE_TORCH_COMPILE}" == "1" ]]; then
|
| 47 |
+
ENABLE_TORCH_COMPILE=0
|
| 48 |
+
fi
|
| 49 |
+
if [[ "${DATA_PATH}" == *"lm1b_train_parquet"* && "${NUM_WORKERS}" != "0" ]]; then
|
| 50 |
+
echo "LM1B has only 9 parquet shards; forcing NUM_WORKERS=0 to avoid empty DDP dataloader shards." >&2
|
| 51 |
+
NUM_WORKERS=0
|
| 52 |
+
fi
|
| 53 |
+
|
| 54 |
+
COMPILE_ARGS=()
|
| 55 |
+
if [[ "${ENABLE_TORCH_COMPILE}" == "1" ]]; then
|
| 56 |
+
COMPILE_ARGS+=(--torch_compile --compile_mode reduce-overhead)
|
| 57 |
+
fi
|
| 58 |
+
RESUME_ARGS=()
|
| 59 |
+
if [[ -n "${RESUME_PATH}" ]]; then
|
| 60 |
+
RESUME_ARGS+=(--resume_path "${RESUME_PATH}")
|
| 61 |
+
fi
|
| 62 |
+
TEXT_COLUMN_ARGS=()
|
| 63 |
+
if [[ -n "${TEXT_COLUMN}" ]]; then
|
| 64 |
+
TEXT_COLUMN_ARGS+=(--text_column "${TEXT_COLUMN}")
|
| 65 |
+
fi
|
| 66 |
+
|
| 67 |
+
if [[ -f "${SAVE_DIR}/args.json" && -z "${RESUME_PATH}" && "${ALLOW_EXISTING_SAVE_DIR}" != "1" ]]; then
|
| 68 |
+
echo "Refusing to start because SAVE_DIR already contains args.json: ${SAVE_DIR}" >&2
|
| 69 |
+
echo "Use a new RUN_NAME/SAVE_DIR, set RESUME_PATH to resume, or set ALLOW_EXISTING_SAVE_DIR=1 intentionally." >&2
|
| 70 |
+
exit 2
|
| 71 |
+
fi
|
| 72 |
+
|
| 73 |
+
mkdir -p logs runs "${SAVE_DIR}"
|
| 74 |
+
echo "[launch] method=logisticnormal_linearmean_categorical_fullvocab_c1024_fullycoupled host=$(hostname) time=$(date -Iseconds)"
|
| 75 |
+
echo "[launch] cwd=$(pwd)"
|
| 76 |
+
echo "[launch] run_name=${RUN_NAME}"
|
| 77 |
+
echo "[launch] save_dir=${SAVE_DIR}"
|
| 78 |
+
echo "[launch] log_file=${LOG_FILE}"
|
| 79 |
+
|
| 80 |
+
python -m torch.distributed.run \
|
| 81 |
+
--nnodes="${NNODES}" \
|
| 82 |
+
--nproc_per_node="${NPROC_PER_NODE}" \
|
| 83 |
+
--node_rank="${NODE_RANK}" \
|
| 84 |
+
--master_addr="${MASTER_ADDR}" \
|
| 85 |
+
--master_port="${MASTER_PORT}" \
|
| 86 |
+
train.py \
|
| 87 |
+
--data_path "${DATA_PATH}" \
|
| 88 |
+
"${TEXT_COLUMN_ARGS[@]}" \
|
| 89 |
+
--openwebtext_split "${OPENWEBTEXT_SPLIT}" \
|
| 90 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 91 |
+
--save_dir "${SAVE_DIR}" \
|
| 92 |
+
--wrap \
|
| 93 |
+
--wrap_mode "${WRAP_MODE}" \
|
| 94 |
+
--wrap_record_buffer_size "${WRAP_RECORD_BUFFER_SIZE}" \
|
| 95 |
+
--max_len "${MAX_LEN}" \
|
| 96 |
+
--batch_size "${PER_GPU_BATCH_SIZE}" \
|
| 97 |
+
--num_workers "${NUM_WORKERS}" \
|
| 98 |
+
--global_batch_size "${GLOBAL_BATCH_SIZE}" \
|
| 99 |
+
--total_steps "${TOTAL_STEPS}" \
|
| 100 |
+
--log_every "${LOG_EVERY}" \
|
| 101 |
+
--eval_every "${EVAL_EVERY}" \
|
| 102 |
+
--save_every "${SAVE_EVERY}" \
|
| 103 |
+
--latest_every "${LATEST_EVERY}" \
|
| 104 |
+
--lr 3e-4 \
|
| 105 |
+
--weight_decay 0 \
|
| 106 |
+
--adam_beta1 0.9 \
|
| 107 |
+
--adam_beta2 0.999 \
|
| 108 |
+
--adam_eps 1e-8 \
|
| 109 |
+
--warmup_steps "${WARMUP_STEPS}" \
|
| 110 |
+
--lr_schedule constant_warmup \
|
| 111 |
+
--grad_clip 1.0 \
|
| 112 |
+
--seed 123 \
|
| 113 |
+
--d_model 768 \
|
| 114 |
+
--cond_dim 128 \
|
| 115 |
+
--n_layers 12 \
|
| 116 |
+
--n_heads 12 \
|
| 117 |
+
--dim_ff 3072 \
|
| 118 |
+
--dropout 0.1 \
|
| 119 |
+
--model_type ddit \
|
| 120 |
+
--state_format prob \
|
| 121 |
+
--bridge dirichlet \
|
| 122 |
+
--target_loss hard_ce \
|
| 123 |
+
--target_prob 1.0 \
|
| 124 |
+
--min_t 0.0 \
|
| 125 |
+
--max_t 1.0 \
|
| 126 |
+
--dual_t \
|
| 127 |
+
--corrupt_t_mode same \
|
| 128 |
+
--corrupt_min_t 0.0 \
|
| 129 |
+
--corrupt_max_t 1.0 \
|
| 130 |
+
--min_mask_ratio 0.1 \
|
| 131 |
+
--max_mask_ratio 1.0 \
|
| 132 |
+
--wrong_token_replace_prob 1.0 \
|
| 133 |
+
--wrong_token_schedule linear_t \
|
| 134 |
+
--wrong_token_exp_k 1.0 \
|
| 135 |
+
--dirichlet_concentration_min 1.0 \
|
| 136 |
+
--dirichlet_concentration_max 1024.0 \
|
| 137 |
+
--dirichlet_endpoint_mode categorical_dual_t \
|
| 138 |
+
--dirichlet_semantic_t_mode same \
|
| 139 |
+
--dirichlet_semantic_t_value 0.0 \
|
| 140 |
+
--categorical_wrong_from_full_vocab \
|
| 141 |
+
--simplex_bridge_sampler logistic_normal_linear_mean \
|
| 142 |
+
--logistic_normal_sigma_min 0.18 \
|
| 143 |
+
--logistic_normal_sigma_max 2.2 \
|
| 144 |
+
--logistic_normal_tau_min 0.65 \
|
| 145 |
+
--logistic_normal_tau_max 1.15 \
|
| 146 |
+
--eps 1e-8 \
|
| 147 |
+
--infer_steps 128 \
|
| 148 |
+
--decode_damping 1.0 \
|
| 149 |
+
--max_gamma 1.0 \
|
| 150 |
+
--decode_solver flowmap \
|
| 151 |
+
--noise_init logistic_normal \
|
| 152 |
+
--bridge_noise_init logistic_normal \
|
| 153 |
+
--noise_sigma -1 \
|
| 154 |
+
"${RESUME_ARGS[@]}" \
|
| 155 |
+
"${COMPILE_ARGS[@]}" \
|
| 156 |
+
--bf16 2>&1 | tee -a "${LOG_FILE}"
|
LTA_openwebtext_dualt/scripts/launch_lta_lm1b_compact_gpt2bpe_v8192_len128_fullycoupled_4gpu.sh
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
|
| 6 |
+
export CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0,1,2,3}"
|
| 7 |
+
export OMP_NUM_THREADS="${OMP_NUM_THREADS:-1}"
|
| 8 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 9 |
+
export TOKENIZERS_PARALLELISM=false
|
| 10 |
+
export PYTHONUNBUFFERED=1
|
| 11 |
+
export NCCL_DEBUG="${NCCL_DEBUG:-WARN}"
|
| 12 |
+
export TORCH_DISTRIBUTED_TIMEOUT="${TORCH_DISTRIBUTED_TIMEOUT:-3600}"
|
| 13 |
+
|
| 14 |
+
DATA_PATH="${DATA_PATH:-/e2e-data/evad-tech-vla/wanghan58/data/embedded-language-flows/lm1b-compact-gpt2bpe-v8192-stream128}"
|
| 15 |
+
TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/models/lta_tokenizers/owt_compact_gpt2bpe_v8192/tokenizer.json}"
|
| 16 |
+
|
| 17 |
+
NNODES="${NNODES:-1}"
|
| 18 |
+
NPROC_PER_NODE="${NPROC_PER_NODE:-4}"
|
| 19 |
+
NODE_RANK="${NODE_RANK:-0}"
|
| 20 |
+
MASTER_ADDR="${MASTER_ADDR:-127.0.0.1}"
|
| 21 |
+
MASTER_PORT="${MASTER_PORT:-32381}"
|
| 22 |
+
|
| 23 |
+
PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-64}"
|
| 24 |
+
GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 25 |
+
TOTAL_STEPS="${TOTAL_STEPS:-1000000}"
|
| 26 |
+
WARMUP_STEPS="${WARMUP_STEPS:-2000}"
|
| 27 |
+
NUM_WORKERS="${NUM_WORKERS:-8}"
|
| 28 |
+
DATALOADER_PREFETCH_FACTOR="${DATALOADER_PREFETCH_FACTOR:-4}"
|
| 29 |
+
LOG_EVERY="${LOG_EVERY:-50}"
|
| 30 |
+
SAVE_EVERY="${SAVE_EVERY:-10000}"
|
| 31 |
+
LATEST_EVERY="${LATEST_EVERY:-1000}"
|
| 32 |
+
EVAL_EVERY="${EVAL_EVERY:-0}"
|
| 33 |
+
ALLOW_EXISTING_SAVE_DIR="${ALLOW_EXISTING_SAVE_DIR:-0}"
|
| 34 |
+
ALLOW_TF32="${ALLOW_TF32:-1}"
|
| 35 |
+
DRY_RUN="${DRY_RUN:-0}"
|
| 36 |
+
RESUME_PATH="${RESUME_PATH:-}"
|
| 37 |
+
|
| 38 |
+
LR="${LR:-6e-4}"
|
| 39 |
+
MIN_LR="${MIN_LR:-6e-5}"
|
| 40 |
+
WEIGHT_DECAY="${WEIGHT_DECAY:-0.1}"
|
| 41 |
+
OUTPUT_WEIGHT_DECAY="${OUTPUT_WEIGHT_DECAY:--1}"
|
| 42 |
+
ADAM_BETA1="${ADAM_BETA1:-0.9}"
|
| 43 |
+
ADAM_BETA2="${ADAM_BETA2:-0.95}"
|
| 44 |
+
ADAM_EPS="${ADAM_EPS:-1e-8}"
|
| 45 |
+
GRAD_CLIP="${GRAD_CLIP:-1.0}"
|
| 46 |
+
EMA_DECAY="${EMA_DECAY:-0.0}"
|
| 47 |
+
EMA_START_STEP="${EMA_START_STEP:-0}"
|
| 48 |
+
|
| 49 |
+
T_SAMPLING_MODE="${T_SAMPLING_MODE:-uniform}"
|
| 50 |
+
T_SAMPLING_POWER="${T_SAMPLING_POWER:-1.0}"
|
| 51 |
+
T_SAMPLING_EPS="${T_SAMPLING_EPS:-1e-4}"
|
| 52 |
+
T_SAMPLING_LOGIT_MEAN="${T_SAMPLING_LOGIT_MEAN:--1.5}"
|
| 53 |
+
T_SAMPLING_LOGIT_STD="${T_SAMPLING_LOGIT_STD:-0.8}"
|
| 54 |
+
MIN_MASK_RATIO="${MIN_MASK_RATIO:-1.0}"
|
| 55 |
+
MAX_MASK_RATIO="${MAX_MASK_RATIO:-1.0}"
|
| 56 |
+
|
| 57 |
+
LOSS_T_WEIGHT_MODE="${LOSS_T_WEIGHT_MODE:-none}"
|
| 58 |
+
LOSS_T_MIN_WEIGHT="${LOSS_T_MIN_WEIGHT:-0.0}"
|
| 59 |
+
LOSS_T_DROP_BELOW="${LOSS_T_DROP_BELOW:-0.2}"
|
| 60 |
+
|
| 61 |
+
RUN_NAME="${RUN_NAME:-lta_lm1b_compact_gpt2bpe_v8192_len128_fullycoupled_rmsnorm_nobias_adamw_wd0p1_${T_SAMPLING_MODE}t_hardce_mask${MIN_MASK_RATIO}-${MAX_MASK_RATIO}_fp32_ddit768x12_gbs${GLOBAL_BATCH_SIZE}_4gpu_1m_$(date +%Y%m%d_%H%M%S)}"
|
| 62 |
+
SAVE_DIR="${SAVE_DIR:-runs/${RUN_NAME}}"
|
| 63 |
+
LOG_DIR="${LOG_DIR:-logs/lm1b_compact_gpt2bpe_v8192_len128_fullycoupled_4gpu}"
|
| 64 |
+
LOG_FILE="${LOG_FILE:-${LOG_DIR}/${RUN_NAME}.log}"
|
| 65 |
+
|
| 66 |
+
if [[ ! -f "${TOKENIZER_PATH}" ]]; then
|
| 67 |
+
echo "Missing tokenizer: ${TOKENIZER_PATH}" >&2
|
| 68 |
+
exit 2
|
| 69 |
+
fi
|
| 70 |
+
if [[ ! -d "${DATA_PATH}" ]]; then
|
| 71 |
+
echo "Missing tokenized dataset: ${DATA_PATH}" >&2
|
| 72 |
+
echo "Build it with: bash scripts/build_lta_lm1b_compact_gpt2bpe_v8192_stream128_np8.sh" >&2
|
| 73 |
+
exit 2
|
| 74 |
+
fi
|
| 75 |
+
if [[ -f "${SAVE_DIR}/args.json" && "${ALLOW_EXISTING_SAVE_DIR}" != "1" ]]; then
|
| 76 |
+
echo "Refusing to start because SAVE_DIR already contains args.json: ${SAVE_DIR}" >&2
|
| 77 |
+
exit 2
|
| 78 |
+
fi
|
| 79 |
+
|
| 80 |
+
mkdir -p "${LOG_DIR}" "${SAVE_DIR}"
|
| 81 |
+
|
| 82 |
+
TF32_FLAG="--allow_tf32"
|
| 83 |
+
TF32_LABEL="true"
|
| 84 |
+
if [[ "${ALLOW_TF32}" == "0" || "${ALLOW_TF32}" == "false" || "${ALLOW_TF32}" == "False" ]]; then
|
| 85 |
+
TF32_FLAG="--no-allow_tf32"
|
| 86 |
+
TF32_LABEL="false"
|
| 87 |
+
fi
|
| 88 |
+
|
| 89 |
+
NUM_EXAMPLES=$(python - <<PY
|
| 90 |
+
import json
|
| 91 |
+
from pathlib import Path
|
| 92 |
+
from datasets import Sequence, load_from_disk
|
| 93 |
+
from datasets.features import features as hf_features
|
| 94 |
+
hf_features._FEATURE_TYPES.setdefault("List", Sequence)
|
| 95 |
+
root = Path("${DATA_PATH}")
|
| 96 |
+
meta = root / "elf_multi_part_meta.json"
|
| 97 |
+
if meta.exists():
|
| 98 |
+
print(int(json.loads(meta.read_text()).get("num_examples", 0)))
|
| 99 |
+
else:
|
| 100 |
+
parts = root / "parts"
|
| 101 |
+
if parts.is_dir():
|
| 102 |
+
print(sum(len(load_from_disk(str(p))) for p in sorted(parts.iterdir()) if p.is_dir()))
|
| 103 |
+
else:
|
| 104 |
+
print(len(load_from_disk(str(root))))
|
| 105 |
+
PY
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
WORLD_SIZE=$(( NNODES * NPROC_PER_NODE ))
|
| 109 |
+
GRAD_ACCUM=$(( (GLOBAL_BATCH_SIZE + PER_GPU_BATCH_SIZE * WORLD_SIZE - 1) / (PER_GPU_BATCH_SIZE * WORLD_SIZE) ))
|
| 110 |
+
|
| 111 |
+
echo "[launch-lm1b-v8192] run_name=${RUN_NAME}"
|
| 112 |
+
echo "[launch-lm1b-v8192] save_dir=${SAVE_DIR}"
|
| 113 |
+
echo "[launch-lm1b-v8192] log_file=${LOG_FILE}"
|
| 114 |
+
echo "[launch-lm1b-v8192] data_path=${DATA_PATH}"
|
| 115 |
+
echo "[launch-lm1b-v8192] tokenizer=${TOKENIZER_PATH}"
|
| 116 |
+
echo "[launch-lm1b-v8192] examples=${NUM_EXAMPLES} max_len=128 total_steps=${TOTAL_STEPS} world_size=${WORLD_SIZE} grad_accum=${GRAD_ACCUM} save_every=${SAVE_EVERY}"
|
| 117 |
+
echo "[launch-lm1b-v8192] model=ddit d768 x12 h12 ff3072 rmsnorm no_bias dropout0"
|
| 118 |
+
echo "[launch-lm1b-v8192] recipe=dirichlet categorical_dual_t hard_ce target_prob1 mask=${MIN_MASK_RATIO}->${MAX_MASK_RATIO} t=${T_SAMPLING_MODE} tf32=${TF32_LABEL}"
|
| 119 |
+
|
| 120 |
+
if [[ "${DRY_RUN}" == "1" || "${DRY_RUN}" == "true" || "${DRY_RUN}" == "True" ]]; then
|
| 121 |
+
echo "[launch-lm1b-v8192] DRY_RUN=1, validated setup; skipping torchrun."
|
| 122 |
+
exit 0
|
| 123 |
+
fi
|
| 124 |
+
|
| 125 |
+
RESUME_ARGS=()
|
| 126 |
+
if [[ -n "${RESUME_PATH}" ]]; then
|
| 127 |
+
RESUME_ARGS+=(--resume_path "${RESUME_PATH}")
|
| 128 |
+
fi
|
| 129 |
+
|
| 130 |
+
python -m torch.distributed.run \
|
| 131 |
+
--nnodes="${NNODES}" \
|
| 132 |
+
--nproc_per_node="${NPROC_PER_NODE}" \
|
| 133 |
+
--node_rank="${NODE_RANK}" \
|
| 134 |
+
--master_addr="${MASTER_ADDR}" \
|
| 135 |
+
--master_port="${MASTER_PORT}" \
|
| 136 |
+
train.py \
|
| 137 |
+
"${RESUME_ARGS[@]}" \
|
| 138 |
+
--data_path "${DATA_PATH}" \
|
| 139 |
+
--tokenized_hf \
|
| 140 |
+
--tokenized_pad_token pad \
|
| 141 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 142 |
+
--save_dir "${SAVE_DIR}" \
|
| 143 |
+
--max_len 128 \
|
| 144 |
+
--batch_size "${PER_GPU_BATCH_SIZE}" \
|
| 145 |
+
--global_batch_size "${GLOBAL_BATCH_SIZE}" \
|
| 146 |
+
--num_workers "${NUM_WORKERS}" \
|
| 147 |
+
--dataloader_prefetch_factor "${DATALOADER_PREFETCH_FACTOR}" \
|
| 148 |
+
--epochs 0 \
|
| 149 |
+
--total_steps "${TOTAL_STEPS}" \
|
| 150 |
+
--warmup_steps "${WARMUP_STEPS}" \
|
| 151 |
+
--log_every "${LOG_EVERY}" \
|
| 152 |
+
--eval_every "${EVAL_EVERY}" \
|
| 153 |
+
--save_every "${SAVE_EVERY}" \
|
| 154 |
+
--latest_every "${LATEST_EVERY}" \
|
| 155 |
+
--optimizer adamw \
|
| 156 |
+
--lr "${LR}" \
|
| 157 |
+
--lr_schedule cosine \
|
| 158 |
+
--min_lr "${MIN_LR}" \
|
| 159 |
+
--weight_decay "${WEIGHT_DECAY}" \
|
| 160 |
+
--output_weight_decay "${OUTPUT_WEIGHT_DECAY}" \
|
| 161 |
+
--adamw_param_groups nanogpt \
|
| 162 |
+
--adam_beta1 "${ADAM_BETA1}" \
|
| 163 |
+
--adam_beta2 "${ADAM_BETA2}" \
|
| 164 |
+
--adam_eps "${ADAM_EPS}" \
|
| 165 |
+
--ema_decay "${EMA_DECAY}" \
|
| 166 |
+
--ema_start_step "${EMA_START_STEP}" \
|
| 167 |
+
--grad_clip "${GRAD_CLIP}" \
|
| 168 |
+
--seed 123 \
|
| 169 |
+
--d_model 768 \
|
| 170 |
+
--cond_dim 128 \
|
| 171 |
+
--n_layers 12 \
|
| 172 |
+
--n_heads 12 \
|
| 173 |
+
--dim_ff 3072 \
|
| 174 |
+
--dropout 0.0 \
|
| 175 |
+
--no-output_bias \
|
| 176 |
+
--norm_type rmsnorm \
|
| 177 |
+
--model_type ddit \
|
| 178 |
+
--state_format prob \
|
| 179 |
+
--bridge dirichlet \
|
| 180 |
+
--target_loss hard_ce \
|
| 181 |
+
--loss_t_weight_mode "${LOSS_T_WEIGHT_MODE}" \
|
| 182 |
+
--loss_t_min_weight "${LOSS_T_MIN_WEIGHT}" \
|
| 183 |
+
--loss_t_drop_below "${LOSS_T_DROP_BELOW}" \
|
| 184 |
+
--target_prob 1.0 \
|
| 185 |
+
--min_t 0.0 \
|
| 186 |
+
--max_t 1.0 \
|
| 187 |
+
--t_sampling_mode "${T_SAMPLING_MODE}" \
|
| 188 |
+
--t_sampling_power "${T_SAMPLING_POWER}" \
|
| 189 |
+
--t_sampling_logit_mean "${T_SAMPLING_LOGIT_MEAN}" \
|
| 190 |
+
--t_sampling_logit_std "${T_SAMPLING_LOGIT_STD}" \
|
| 191 |
+
--t_sampling_eps "${T_SAMPLING_EPS}" \
|
| 192 |
+
--dual_t \
|
| 193 |
+
--corrupt_t_mode same \
|
| 194 |
+
--corrupt_min_t 0.0 \
|
| 195 |
+
--corrupt_max_t 1.0 \
|
| 196 |
+
--min_mask_ratio "${MIN_MASK_RATIO}" \
|
| 197 |
+
--max_mask_ratio "${MAX_MASK_RATIO}" \
|
| 198 |
+
--wrong_token_replace_prob 1.0 \
|
| 199 |
+
--wrong_token_schedule linear_t \
|
| 200 |
+
--wrong_token_exp_k 1.0 \
|
| 201 |
+
--dirichlet_concentration_min 1.0 \
|
| 202 |
+
--dirichlet_concentration_max 1024 \
|
| 203 |
+
--dirichlet_endpoint_mode categorical_dual_t \
|
| 204 |
+
--dirichlet_semantic_t_mode same \
|
| 205 |
+
--dirichlet_semantic_t_value 0.0 \
|
| 206 |
+
--categorical_wrong_from_full_vocab \
|
| 207 |
+
--simplex_bridge_sampler dirichlet \
|
| 208 |
+
--eps 1e-8 \
|
| 209 |
+
--infer_steps 128 \
|
| 210 |
+
--decode_damping 1.0 \
|
| 211 |
+
--max_gamma 1.0 \
|
| 212 |
+
--decode_solver flowmap \
|
| 213 |
+
--noise_init logistic_normal \
|
| 214 |
+
--bridge_noise_init logistic_normal \
|
| 215 |
+
--noise_sigma -1 \
|
| 216 |
+
"${TF32_FLAG}" \
|
| 217 |
+
--ddp_gradient_as_bucket_view \
|
| 218 |
+
2>&1 | tee -a "${LOG_FILE}"
|
| 219 |
+
|
LTA_openwebtext_dualt/scripts/launch_lta_openwebtext_dualt_8gpu_aligned.sh
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 6 |
+
export TOKENIZERS_PARALLELISM=false
|
| 7 |
+
export PYTHONUNBUFFERED=1
|
| 8 |
+
export NCCL_DEBUG="${NCCL_DEBUG:-WARN}"
|
| 9 |
+
export TORCH_DISTRIBUTED_TIMEOUT="${TORCH_DISTRIBUTED_TIMEOUT:-3600}"
|
| 10 |
+
|
| 11 |
+
# FLM-repo-aligned engineering defaults:
|
| 12 |
+
# - GPT-2 OpenWebText split, wrapped fixed length 1024
|
| 13 |
+
# - DDiT small: 12 layers, d=768, 12 heads, FF=3072, adaLN-zero
|
| 14 |
+
# - global batch 512, per-GPU local batch 32 on 8 GPUs
|
| 15 |
+
# - bf16, flash-attn when available, torch.compile max-autotune
|
| 16 |
+
# - AdamW lr 3e-4, no weight decay, 2500 warmup, constant schedule
|
| 17 |
+
#
|
| 18 |
+
# Algorithm remains ours:
|
| 19 |
+
# - probability-state LTA
|
| 20 |
+
# - Dirichlet bridge
|
| 21 |
+
# - hard CE target and one-hot clean anchors/endpoints
|
| 22 |
+
# - wrong-token corruption is scheduled by corruption time: p_wrong = 1 - t_corrupt
|
| 23 |
+
# - dual-t: model/flow time is separate from corruption/support time
|
| 24 |
+
|
| 25 |
+
RUN_NAME="${RUN_NAME:-lta_owt_dirichlet_dualt_onehot_hardce_ddit_small_len1024_gbs512_8gpu}"
|
| 26 |
+
DATA_PATH="${DATA_PATH:-/e2e-data/evad-tech-vla/wanghan58/data/small_benchmarks/langflow_2604_11748/openwebtext}"
|
| 27 |
+
TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-standard/tokenizer.json}"
|
| 28 |
+
SAVE_DIR="${SAVE_DIR:-runs/${RUN_NAME}}"
|
| 29 |
+
LOG_FILE="${LOG_FILE:-logs/${RUN_NAME}.log}"
|
| 30 |
+
|
| 31 |
+
NNODES="${NNODES:-1}"
|
| 32 |
+
NPROC_PER_NODE="${NPROC_PER_NODE:-8}"
|
| 33 |
+
NODE_RANK="${NODE_RANK:-0}"
|
| 34 |
+
MASTER_ADDR="${MASTER_ADDR:-127.0.0.1}"
|
| 35 |
+
MASTER_PORT="${MASTER_PORT:-29621}"
|
| 36 |
+
|
| 37 |
+
GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 38 |
+
PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-32}"
|
| 39 |
+
TOTAL_STEPS="${TOTAL_STEPS:-1500000}"
|
| 40 |
+
WARMUP_STEPS="${WARMUP_STEPS:-2500}"
|
| 41 |
+
MAX_LEN="${MAX_LEN:-1024}"
|
| 42 |
+
NUM_WORKERS="${NUM_WORKERS:-4}"
|
| 43 |
+
LOG_EVERY="${LOG_EVERY:-100}"
|
| 44 |
+
SAVE_EVERY="${SAVE_EVERY:-20000}"
|
| 45 |
+
EVAL_EVERY="${EVAL_EVERY:-0}"
|
| 46 |
+
|
| 47 |
+
mkdir -p logs runs "${SAVE_DIR}"
|
| 48 |
+
|
| 49 |
+
python -m torch.distributed.run \
|
| 50 |
+
--nnodes="${NNODES}" \
|
| 51 |
+
--nproc_per_node="${NPROC_PER_NODE}" \
|
| 52 |
+
--node_rank="${NODE_RANK}" \
|
| 53 |
+
--master_addr="${MASTER_ADDR}" \
|
| 54 |
+
--master_port="${MASTER_PORT}" \
|
| 55 |
+
train.py \
|
| 56 |
+
--data_path "${DATA_PATH}" \
|
| 57 |
+
--text_column text \
|
| 58 |
+
--openwebtext_split train_minus_100k \
|
| 59 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 60 |
+
--save_dir "${SAVE_DIR}" \
|
| 61 |
+
--wrap \
|
| 62 |
+
--max_len "${MAX_LEN}" \
|
| 63 |
+
--batch_size "${PER_GPU_BATCH_SIZE}" \
|
| 64 |
+
--num_workers "${NUM_WORKERS}" \
|
| 65 |
+
--global_batch_size "${GLOBAL_BATCH_SIZE}" \
|
| 66 |
+
--total_steps "${TOTAL_STEPS}" \
|
| 67 |
+
--log_every "${LOG_EVERY}" \
|
| 68 |
+
--eval_every "${EVAL_EVERY}" \
|
| 69 |
+
--save_every "${SAVE_EVERY}" \
|
| 70 |
+
--lr 3e-4 \
|
| 71 |
+
--weight_decay 0 \
|
| 72 |
+
--adam_beta1 0.9 \
|
| 73 |
+
--adam_beta2 0.999 \
|
| 74 |
+
--adam_eps 1e-8 \
|
| 75 |
+
--warmup_steps "${WARMUP_STEPS}" \
|
| 76 |
+
--lr_schedule constant_warmup \
|
| 77 |
+
--grad_clip 1.0 \
|
| 78 |
+
--seed 123 \
|
| 79 |
+
--d_model 768 \
|
| 80 |
+
--cond_dim 128 \
|
| 81 |
+
--n_layers 12 \
|
| 82 |
+
--n_heads 12 \
|
| 83 |
+
--dim_ff 3072 \
|
| 84 |
+
--dropout 0.1 \
|
| 85 |
+
--model_type ddit \
|
| 86 |
+
--state_format prob \
|
| 87 |
+
--bridge dirichlet \
|
| 88 |
+
--target_loss hard_ce \
|
| 89 |
+
--target_prob 1.0 \
|
| 90 |
+
--min_t 0.0 \
|
| 91 |
+
--max_t 1.0 \
|
| 92 |
+
--dual_t \
|
| 93 |
+
--corrupt_t_mode independent \
|
| 94 |
+
--corrupt_min_t 0.0 \
|
| 95 |
+
--corrupt_max_t 1.0 \
|
| 96 |
+
--min_mask_ratio 0.1 \
|
| 97 |
+
--max_mask_ratio 1.0 \
|
| 98 |
+
--wrong_token_replace_prob 1.0 \
|
| 99 |
+
--wrong_token_schedule linear_t \
|
| 100 |
+
--wrong_token_exp_k 1.0 \
|
| 101 |
+
--dirichlet_concentration_min 1.0 \
|
| 102 |
+
--dirichlet_concentration_max 1024.0 \
|
| 103 |
+
--eps 1e-8 \
|
| 104 |
+
--infer_steps 1024 \
|
| 105 |
+
--decode_damping 1.0 \
|
| 106 |
+
--max_gamma 1.0 \
|
| 107 |
+
--decode_solver flowmap \
|
| 108 |
+
--noise_init logistic_normal \
|
| 109 |
+
--bridge_noise_init logistic_normal \
|
| 110 |
+
--noise_sigma -1 \
|
| 111 |
+
--torch_compile \
|
| 112 |
+
--compile_mode max-autotune \
|
| 113 |
+
--bf16 2>&1 | tee -a "${LOG_FILE}"
|
LTA_openwebtext_dualt/scripts/launch_lta_owt_compact_gpt2bpe_v2048_elfaligned_logitnormal_tokenized_8gpu.sh
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
|
| 6 |
+
export VOCAB_SIZE=2048
|
| 7 |
+
export DATA_PATH="${DATA_PATH:-/e2e-data/evad-tech-vla/wanghan58/data/embedded-language-flows/openwebtext-compact-gpt2bpe-v2048-stream1024-train-minus-100k}"
|
| 8 |
+
export TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/models/lta_tokenizers/owt_compact_gpt2bpe_v2048/tokenizer.json}"
|
| 9 |
+
|
| 10 |
+
export CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0,1,2,3,4,5,6,7}"
|
| 11 |
+
export NPROC_PER_NODE="${NPROC_PER_NODE:-8}"
|
| 12 |
+
export MASTER_PORT="${MASTER_PORT:-32241}"
|
| 13 |
+
|
| 14 |
+
export GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 15 |
+
export PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-32}"
|
| 16 |
+
export EPOCHS="${EPOCHS:-5}"
|
| 17 |
+
export NUM_WORKERS="${NUM_WORKERS:-8}"
|
| 18 |
+
export LOG_EVERY="${LOG_EVERY:-100}"
|
| 19 |
+
export LATEST_EVERY="${LATEST_EVERY:-1000}"
|
| 20 |
+
export EVAL_EVERY="${EVAL_EVERY:-0}"
|
| 21 |
+
|
| 22 |
+
# Same recipe as the current OWT ELF-aligned runs: fp32 params/activations,
|
| 23 |
+
# TF32 matmul allowed, RMSNorm, no output bias, Muon+Adam fallback wd=0.1.
|
| 24 |
+
export ALLOW_TF32="${ALLOW_TF32:-1}"
|
| 25 |
+
export TARGET_LOSS="${TARGET_LOSS:-hard_ce}"
|
| 26 |
+
export T_LOGIT_MEAN="${T_LOGIT_MEAN:--1.5}"
|
| 27 |
+
export T_LOGIT_STD="${T_LOGIT_STD:-0.8}"
|
| 28 |
+
export WEIGHT_DECAY="${WEIGHT_DECAY:-0.1}"
|
| 29 |
+
export OUTPUT_INIT_STD="${OUTPUT_INIT_STD:-0.0}"
|
| 30 |
+
|
| 31 |
+
export LOG_DIR="${LOG_DIR:-logs/compact_gpt2bpe_v2048_stream1024_8gpu}"
|
| 32 |
+
export RUN_NAME="${RUN_NAME:-lta_owt_compact_gpt2bpe_v2048_stream1024_elfaligned_dditelf_muon_logitnormal_m1p5_s0p8_hardce_wd0p1_gbs512_8gpu_5epoch_$(date +%Y%m%d_%H%M%S)}"
|
| 33 |
+
|
| 34 |
+
exec bash scripts/launch_lta_owt_compact_gpt2bpe_elfaligned_logitnormal_tokenized_8gpu.sh "$@"
|
LTA_openwebtext_dualt/scripts/launch_lta_owt_fullycoupled_logitnormal_mid_mask1_wd0p1_fp32_8gpu.sh
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
|
| 6 |
+
export CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0,1,2,3,4,5,6,7}"
|
| 7 |
+
export OMP_NUM_THREADS="${OMP_NUM_THREADS:-1}"
|
| 8 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 9 |
+
export TOKENIZERS_PARALLELISM=false
|
| 10 |
+
export PYTHONUNBUFFERED=1
|
| 11 |
+
export NCCL_DEBUG="${NCCL_DEBUG:-WARN}"
|
| 12 |
+
export TORCH_DISTRIBUTED_TIMEOUT="${TORCH_DISTRIBUTED_TIMEOUT:-3600}"
|
| 13 |
+
|
| 14 |
+
# Fully-coupled OWT baseline with FP32 params/activations and nanoGPT-style AdamW decay:
|
| 15 |
+
# decay: matrix / embedding params (p.dim() >= 2)
|
| 16 |
+
# no decay: bias / norm / 1D params
|
| 17 |
+
# This intentionally does NOT pass --bf16. TF32 is enabled by default so H200 uses
|
| 18 |
+
# Tensor Cores; set ALLOW_TF32=0 for strict FP32 debugging.
|
| 19 |
+
|
| 20 |
+
T_SAMPLING_MODE="${T_SAMPLING_MODE:-logit_normal}"
|
| 21 |
+
T_SAMPLING_POWER="${T_SAMPLING_POWER:-1.0}"
|
| 22 |
+
T_SAMPLING_EPS="${T_SAMPLING_EPS:-1e-4}"
|
| 23 |
+
T_SAMPLING_LOGIT_MEAN="${T_SAMPLING_LOGIT_MEAN:--0.22}"
|
| 24 |
+
T_SAMPLING_LOGIT_STD="${T_SAMPLING_LOGIT_STD:-0.5}"
|
| 25 |
+
MIN_MASK_RATIO="${MIN_MASK_RATIO:-1.0}"
|
| 26 |
+
MAX_MASK_RATIO="${MAX_MASK_RATIO:-1.0}"
|
| 27 |
+
DDIT_MLP_TYPE="${DDIT_MLP_TYPE:-swiglu}"
|
| 28 |
+
|
| 29 |
+
sanitize_label() {
|
| 30 |
+
printf "%s" "$1" | sed -e 's/-/m/g' -e 's/\./p/g'
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
T_LOGIT_MEAN_LABEL="$(sanitize_label "${T_SAMPLING_LOGIT_MEAN}")"
|
| 34 |
+
T_LOGIT_STD_LABEL="$(sanitize_label "${T_SAMPLING_LOGIT_STD}")"
|
| 35 |
+
MIN_MASK_RATIO_LABEL="$(sanitize_label "${MIN_MASK_RATIO}")"
|
| 36 |
+
MAX_MASK_RATIO_LABEL="$(sanitize_label "${MAX_MASK_RATIO}")"
|
| 37 |
+
|
| 38 |
+
RUN_NAME="${RUN_NAME:-lta_owt_gpt2cached_len1024_fullycoupled_rmsnorm_nobias_${DDIT_MLP_TYPE}_adamw_wd0p1_logitnormal_mid_${T_LOGIT_MEAN_LABEL}_s${T_LOGIT_STD_LABEL}_hardce_mask${MIN_MASK_RATIO_LABEL}-${MAX_MASK_RATIO_LABEL}_nanogpt_fp32_ddit768x12_gbs512_8gpu_1m_$(date +%Y%m%d_%H%M%S)}"
|
| 39 |
+
SAVE_DIR="${SAVE_DIR:-runs/${RUN_NAME}}"
|
| 40 |
+
LOG_DIR="${LOG_DIR:-logs/fullycoupled_logitnormal_mid_mask1_wd0p1_fp32_8gpu}"
|
| 41 |
+
LOG_FILE="${LOG_FILE:-${LOG_DIR}/${RUN_NAME}.log}"
|
| 42 |
+
|
| 43 |
+
DATA_PATH="${DATA_PATH:-/e2e-data/evad-tech-vla/wanghan58/data/small_benchmarks/langflow_2604_11748/openwebtext}"
|
| 44 |
+
OWT_CACHE="${OWT_CACHE:-/e2e-data/evad-tech-vla/wanghan58/data/small_benchmarks/langflow_2604_11748/openwebtext_lta_cached_chunks/gpt2_len1024_train_minus_100k}"
|
| 45 |
+
TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-standard/tokenizer.json}"
|
| 46 |
+
|
| 47 |
+
NNODES="${NNODES:-1}"
|
| 48 |
+
NPROC_PER_NODE="${NPROC_PER_NODE:-8}"
|
| 49 |
+
NODE_RANK="${NODE_RANK:-0}"
|
| 50 |
+
MASTER_ADDR="${MASTER_ADDR:-127.0.0.1}"
|
| 51 |
+
MASTER_PORT="${MASTER_PORT:-31997}"
|
| 52 |
+
|
| 53 |
+
PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-32}"
|
| 54 |
+
GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 55 |
+
TOTAL_STEPS="${TOTAL_STEPS:-1000000}"
|
| 56 |
+
WARMUP_STEPS="${WARMUP_STEPS:-2000}"
|
| 57 |
+
NUM_WORKERS="${NUM_WORKERS:-8}"
|
| 58 |
+
DATALOADER_PREFETCH_FACTOR="${DATALOADER_PREFETCH_FACTOR:-4}"
|
| 59 |
+
LOG_EVERY="${LOG_EVERY:-50}"
|
| 60 |
+
SAVE_EVERY="${SAVE_EVERY:-50000}"
|
| 61 |
+
LATEST_EVERY="${LATEST_EVERY:-1000}"
|
| 62 |
+
EVAL_EVERY="${EVAL_EVERY:-0}"
|
| 63 |
+
ALLOW_EXISTING_SAVE_DIR="${ALLOW_EXISTING_SAVE_DIR:-0}"
|
| 64 |
+
ALLOW_TF32="${ALLOW_TF32:-1}"
|
| 65 |
+
DRY_RUN="${DRY_RUN:-0}"
|
| 66 |
+
|
| 67 |
+
LR="${LR:-6e-4}"
|
| 68 |
+
MIN_LR="${MIN_LR:-6e-5}"
|
| 69 |
+
WEIGHT_DECAY="${WEIGHT_DECAY:-0.1}"
|
| 70 |
+
OUTPUT_WEIGHT_DECAY="${OUTPUT_WEIGHT_DECAY:--1}"
|
| 71 |
+
ADAM_BETA1="${ADAM_BETA1:-0.9}"
|
| 72 |
+
ADAM_BETA2="${ADAM_BETA2:-0.95}"
|
| 73 |
+
ADAM_EPS="${ADAM_EPS:-1e-8}"
|
| 74 |
+
GRAD_CLIP="${GRAD_CLIP:-1.0}"
|
| 75 |
+
EMA_DECAY="${EMA_DECAY:-0.0}"
|
| 76 |
+
EMA_START_STEP="${EMA_START_STEP:-0}"
|
| 77 |
+
LOSS_T_WEIGHT_MODE="${LOSS_T_WEIGHT_MODE:-none}"
|
| 78 |
+
LOSS_T_MIN_WEIGHT="${LOSS_T_MIN_WEIGHT:-0.0}"
|
| 79 |
+
LOSS_T_DROP_BELOW="${LOSS_T_DROP_BELOW:-0.2}"
|
| 80 |
+
|
| 81 |
+
if [[ -f "${SAVE_DIR}/args.json" && "${ALLOW_EXISTING_SAVE_DIR}" != "1" ]]; then
|
| 82 |
+
echo "Refusing to start because SAVE_DIR already contains args.json: ${SAVE_DIR}" >&2
|
| 83 |
+
echo "Use a new RUN_NAME/SAVE_DIR or set ALLOW_EXISTING_SAVE_DIR=1 intentionally." >&2
|
| 84 |
+
exit 2
|
| 85 |
+
fi
|
| 86 |
+
|
| 87 |
+
mkdir -p "${LOG_DIR}" "${SAVE_DIR}"
|
| 88 |
+
|
| 89 |
+
TF32_FLAG="--allow_tf32"
|
| 90 |
+
TF32_LABEL="true"
|
| 91 |
+
if [[ "${ALLOW_TF32}" == "0" || "${ALLOW_TF32}" == "false" || "${ALLOW_TF32}" == "False" ]]; then
|
| 92 |
+
TF32_FLAG="--no-allow_tf32"
|
| 93 |
+
TF32_LABEL="false"
|
| 94 |
+
fi
|
| 95 |
+
|
| 96 |
+
echo "[launch] method=owt_fullycoupled_adamw_wd0p1_nanogpt_fp32 host=$(hostname) time=$(date -Iseconds)"
|
| 97 |
+
echo "[launch] run_name=${RUN_NAME}"
|
| 98 |
+
echo "[launch] save_dir=${SAVE_DIR}"
|
| 99 |
+
echo "[launch] log_file=${LOG_FILE}"
|
| 100 |
+
echo "[launch] data_path=${DATA_PATH}"
|
| 101 |
+
echo "[launch] owt_cache=${OWT_CACHE}"
|
| 102 |
+
echo "[launch] optimizer=adamw lr=${LR} min_lr=${MIN_LR} wd=${WEIGHT_DECAY} output_wd=${OUTPUT_WEIGHT_DECAY} param_groups=nanogpt ema=${EMA_DECAY}"
|
| 103 |
+
echo "[launch] fp32=true bf16=false tf32=${TF32_LABEL} norm_type=rmsnorm output_bias=false ddit_mlp_type=${DDIT_MLP_TYPE} batch=${GLOBAL_BATCH_SIZE} per_gpu=${PER_GPU_BATCH_SIZE}"
|
| 104 |
+
echo "[launch] loss_t_weight_mode=${LOSS_T_WEIGHT_MODE} loss_t_min_weight=${LOSS_T_MIN_WEIGHT} loss_t_drop_below=${LOSS_T_DROP_BELOW}"
|
| 105 |
+
echo "[launch] target_loss=hard_ce t_sampling_mode=${T_SAMPLING_MODE} t_sampling_logit_mean=${T_SAMPLING_LOGIT_MEAN} t_sampling_logit_std=${T_SAMPLING_LOGIT_STD} t_sampling_power=${T_SAMPLING_POWER} t_sampling_eps=${T_SAMPLING_EPS} mask_ratio=${MIN_MASK_RATIO}->${MAX_MASK_RATIO}"
|
| 106 |
+
|
| 107 |
+
if [[ "${DRY_RUN}" == "1" || "${DRY_RUN}" == "true" || "${DRY_RUN}" == "True" ]]; then
|
| 108 |
+
echo "[launch] DRY_RUN=1, validated launch parameters; skipping torchrun."
|
| 109 |
+
exit 0
|
| 110 |
+
fi
|
| 111 |
+
|
| 112 |
+
python -m torch.distributed.run \
|
| 113 |
+
--nnodes="${NNODES}" \
|
| 114 |
+
--nproc_per_node="${NPROC_PER_NODE}" \
|
| 115 |
+
--node_rank="${NODE_RANK}" \
|
| 116 |
+
--master_addr="${MASTER_ADDR}" \
|
| 117 |
+
--master_port="${MASTER_PORT}" \
|
| 118 |
+
train.py \
|
| 119 |
+
--data_path "${DATA_PATH}" \
|
| 120 |
+
--openwebtext_split train_minus_100k \
|
| 121 |
+
--text_column text \
|
| 122 |
+
--detokenizer auto \
|
| 123 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 124 |
+
--save_dir "${SAVE_DIR}" \
|
| 125 |
+
--wrap \
|
| 126 |
+
--wrap_mode stream \
|
| 127 |
+
--owt_cached_chunks \
|
| 128 |
+
--owt_chunk_cache_dir "${OWT_CACHE}" \
|
| 129 |
+
--max_len 1024 \
|
| 130 |
+
--batch_size "${PER_GPU_BATCH_SIZE}" \
|
| 131 |
+
--global_batch_size "${GLOBAL_BATCH_SIZE}" \
|
| 132 |
+
--num_workers "${NUM_WORKERS}" \
|
| 133 |
+
--dataloader_prefetch_factor "${DATALOADER_PREFETCH_FACTOR}" \
|
| 134 |
+
--total_steps "${TOTAL_STEPS}" \
|
| 135 |
+
--warmup_steps "${WARMUP_STEPS}" \
|
| 136 |
+
--log_every "${LOG_EVERY}" \
|
| 137 |
+
--eval_every "${EVAL_EVERY}" \
|
| 138 |
+
--save_every "${SAVE_EVERY}" \
|
| 139 |
+
--latest_every "${LATEST_EVERY}" \
|
| 140 |
+
--optimizer adamw \
|
| 141 |
+
--lr "${LR}" \
|
| 142 |
+
--lr_schedule cosine \
|
| 143 |
+
--min_lr "${MIN_LR}" \
|
| 144 |
+
--weight_decay "${WEIGHT_DECAY}" \
|
| 145 |
+
--output_weight_decay "${OUTPUT_WEIGHT_DECAY}" \
|
| 146 |
+
--adamw_param_groups nanogpt \
|
| 147 |
+
--adam_beta1 "${ADAM_BETA1}" \
|
| 148 |
+
--adam_beta2 "${ADAM_BETA2}" \
|
| 149 |
+
--adam_eps "${ADAM_EPS}" \
|
| 150 |
+
--ema_decay "${EMA_DECAY}" \
|
| 151 |
+
--ema_start_step "${EMA_START_STEP}" \
|
| 152 |
+
--grad_clip "${GRAD_CLIP}" \
|
| 153 |
+
--seed 123 \
|
| 154 |
+
--d_model 768 \
|
| 155 |
+
--cond_dim 128 \
|
| 156 |
+
--n_layers 12 \
|
| 157 |
+
--n_heads 12 \
|
| 158 |
+
--dim_ff 3072 \
|
| 159 |
+
--dropout 0.0 \
|
| 160 |
+
--no-output_bias \
|
| 161 |
+
--norm_type rmsnorm \
|
| 162 |
+
--model_type ddit \
|
| 163 |
+
--ddit_mlp_type "${DDIT_MLP_TYPE}" \
|
| 164 |
+
--state_format prob \
|
| 165 |
+
--bridge dirichlet \
|
| 166 |
+
--target_loss hard_ce \
|
| 167 |
+
--loss_t_weight_mode "${LOSS_T_WEIGHT_MODE}" \
|
| 168 |
+
--loss_t_min_weight "${LOSS_T_MIN_WEIGHT}" \
|
| 169 |
+
--loss_t_drop_below "${LOSS_T_DROP_BELOW}" \
|
| 170 |
+
--target_prob 1.0 \
|
| 171 |
+
--min_t 0.0 \
|
| 172 |
+
--max_t 1.0 \
|
| 173 |
+
--t_sampling_mode "${T_SAMPLING_MODE}" \
|
| 174 |
+
--t_sampling_power "${T_SAMPLING_POWER}" \
|
| 175 |
+
--t_sampling_logit_mean "${T_SAMPLING_LOGIT_MEAN}" \
|
| 176 |
+
--t_sampling_logit_std "${T_SAMPLING_LOGIT_STD}" \
|
| 177 |
+
--t_sampling_eps "${T_SAMPLING_EPS}" \
|
| 178 |
+
--dual_t \
|
| 179 |
+
--corrupt_t_mode same \
|
| 180 |
+
--corrupt_min_t 0.0 \
|
| 181 |
+
--corrupt_max_t 1.0 \
|
| 182 |
+
--min_mask_ratio "${MIN_MASK_RATIO}" \
|
| 183 |
+
--max_mask_ratio "${MAX_MASK_RATIO}" \
|
| 184 |
+
--wrong_token_replace_prob 1.0 \
|
| 185 |
+
--wrong_token_schedule linear_t \
|
| 186 |
+
--wrong_token_exp_k 1.0 \
|
| 187 |
+
--dirichlet_concentration_min 1.0 \
|
| 188 |
+
--dirichlet_concentration_max 1024 \
|
| 189 |
+
--dirichlet_endpoint_mode categorical_dual_t \
|
| 190 |
+
--dirichlet_semantic_t_mode same \
|
| 191 |
+
--dirichlet_semantic_t_value 0.0 \
|
| 192 |
+
--categorical_wrong_from_full_vocab \
|
| 193 |
+
--simplex_bridge_sampler dirichlet \
|
| 194 |
+
--eps 1e-8 \
|
| 195 |
+
--infer_steps 1024 \
|
| 196 |
+
--decode_damping 1.0 \
|
| 197 |
+
--max_gamma 1.0 \
|
| 198 |
+
--decode_solver flowmap \
|
| 199 |
+
--noise_init logistic_normal \
|
| 200 |
+
--bridge_noise_init logistic_normal \
|
| 201 |
+
--noise_sigma -1 \
|
| 202 |
+
"${TF32_FLAG}" \
|
| 203 |
+
--ddp_gradient_as_bucket_view \
|
| 204 |
+
2>&1 | tee -a "${LOG_FILE}"
|
LTA_openwebtext_dualt/scripts/launch_lta_owt_t5_adaln_adamw_wd0p1_rollin_grad_k1_rho025_8gpu.sh
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
set -e
|
| 3 |
+
set -x
|
| 4 |
+
set -o pipefail
|
| 5 |
+
|
| 6 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 7 |
+
|
| 8 |
+
# Use the repo's normal Python/torchrun by default. Set ACTIVATE_ENV only if
|
| 9 |
+
# that environment is known to include torch, datasets, and tokenizers.
|
| 10 |
+
if [[ -n "${ACTIVATE_ENV:-}" ]]; then
|
| 11 |
+
source "${ACTIVATE_ENV}"
|
| 12 |
+
fi
|
| 13 |
+
|
| 14 |
+
free_port() {
|
| 15 |
+
python3 - <<'PY'
|
| 16 |
+
import socket
|
| 17 |
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
| 18 |
+
s.bind(("127.0.0.1", 0))
|
| 19 |
+
print(s.getsockname()[1])
|
| 20 |
+
PY
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
export CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0,1,2,3,4,5,6,7}"
|
| 24 |
+
export NPROC_PER_NODE="${NPROC_PER_NODE:-8}"
|
| 25 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 26 |
+
export TOKENIZERS_PARALLELISM=false
|
| 27 |
+
export PYTHONUNBUFFERED=1
|
| 28 |
+
export NCCL_DEBUG="${NCCL_DEBUG:-WARN}"
|
| 29 |
+
export TORCH_NCCL_AVOID_RECORD_STREAMS=1
|
| 30 |
+
export TORCH_DISTRIBUTED_TIMEOUT="${TORCH_DISTRIBUTED_TIMEOUT:-3600}"
|
| 31 |
+
|
| 32 |
+
DATA_PATH="${DATA_PATH:-/e2e-data/evad-tech-vla/wanghan58/data/embedded-language-flows/openwebtext-t5}"
|
| 33 |
+
TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/models/hf/t5-small/tokenizer.json}"
|
| 34 |
+
GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 35 |
+
PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-32}"
|
| 36 |
+
TOTAL_STEPS="${TOTAL_STEPS:-1000000}"
|
| 37 |
+
MASTER_PORT="${MASTER_PORT:-$(free_port)}"
|
| 38 |
+
LOG_DIR="${LOG_DIR:-logs/elfaligned_t5tokenized_8gpu}"
|
| 39 |
+
|
| 40 |
+
RUN_NAME="${RUN_NAME:-lta_owt_t5_adaln_adamw_wd0p1_rollin_grad_p50_k1_rho0_0p25_uniformt_temp1_synct_gbs${GLOBAL_BATCH_SIZE}_8gpu_1m_$(date +%Y%m%d_%H%M%S)}"
|
| 41 |
+
LOG_FILE="${LOG_FILE:-${LOG_DIR}/${RUN_NAME}.log}"
|
| 42 |
+
|
| 43 |
+
mkdir -p "${LOG_DIR}" "runs/${RUN_NAME}"
|
| 44 |
+
|
| 45 |
+
python - <<'PY'
|
| 46 |
+
import sys
|
| 47 |
+
import torch
|
| 48 |
+
import tokenizers
|
| 49 |
+
|
| 50 |
+
print(f"[launch] python={sys.executable}")
|
| 51 |
+
print(f"[launch] torch={torch.__version__} tokenizers={tokenizers.__version__}")
|
| 52 |
+
PY
|
| 53 |
+
|
| 54 |
+
echo "[launch] run_name=${RUN_NAME}" | tee -a "${LOG_FILE}"
|
| 55 |
+
echo "[launch] cuda=${CUDA_VISIBLE_DEVICES} nproc_per_node=${NPROC_PER_NODE} master_port=${MASTER_PORT}" | tee -a "${LOG_FILE}"
|
| 56 |
+
echo "[launch] global_batch_size=${GLOBAL_BATCH_SIZE} per_gpu_batch_size=${PER_GPU_BATCH_SIZE} total_steps=${TOTAL_STEPS}" | tee -a "${LOG_FILE}"
|
| 57 |
+
echo "[launch] rollout=keep_grad,p50,K1,rhoU0_0p25,sync_t" | tee -a "${LOG_FILE}"
|
| 58 |
+
echo "[launch] data_path=${DATA_PATH}" | tee -a "${LOG_FILE}"
|
| 59 |
+
echo "[launch] tokenizer=${TOKENIZER_PATH}" | tee -a "${LOG_FILE}"
|
| 60 |
+
echo "[launch] log_file=${LOG_FILE}" | tee -a "${LOG_FILE}"
|
| 61 |
+
|
| 62 |
+
torchrun \
|
| 63 |
+
--nproc_per_node="${NPROC_PER_NODE}" \
|
| 64 |
+
--master_port="${MASTER_PORT}" \
|
| 65 |
+
train.py \
|
| 66 |
+
--data_path "${DATA_PATH}" \
|
| 67 |
+
--tokenized_hf \
|
| 68 |
+
--tokenized_pad_token pad \
|
| 69 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 70 |
+
--save_dir "runs/${RUN_NAME}" \
|
| 71 |
+
--max_len 1024 \
|
| 72 |
+
--batch_size "${PER_GPU_BATCH_SIZE}" \
|
| 73 |
+
--global_batch_size "${GLOBAL_BATCH_SIZE}" \
|
| 74 |
+
--num_workers 8 \
|
| 75 |
+
--dataloader_prefetch_factor 4 \
|
| 76 |
+
--epochs 0 \
|
| 77 |
+
--total_steps "${TOTAL_STEPS}" \
|
| 78 |
+
--warmup_steps 1000 \
|
| 79 |
+
--log_every 100 \
|
| 80 |
+
--eval_every 0 \
|
| 81 |
+
--save_every 10000 \
|
| 82 |
+
--latest_every 1000 \
|
| 83 |
+
--optimizer adamw \
|
| 84 |
+
--lr 6e-4 \
|
| 85 |
+
--lr_schedule cosine \
|
| 86 |
+
--min_lr 6e-5 \
|
| 87 |
+
--weight_decay 0.1 \
|
| 88 |
+
--output_weight_decay -1 \
|
| 89 |
+
--adamw_param_groups nanogpt \
|
| 90 |
+
--adam_beta1 0.9 \
|
| 91 |
+
--adam_beta2 0.999 \
|
| 92 |
+
--adam_eps 1e-8 \
|
| 93 |
+
--ema_decay 0.9999 \
|
| 94 |
+
--ema_start_step 0 \
|
| 95 |
+
--grad_clip 1.0 \
|
| 96 |
+
--seed 42 \
|
| 97 |
+
--d_model 768 \
|
| 98 |
+
--cond_dim 128 \
|
| 99 |
+
--n_layers 12 \
|
| 100 |
+
--n_heads 12 \
|
| 101 |
+
--dim_ff 3072 \
|
| 102 |
+
--dropout 0.0 \
|
| 103 |
+
--no-output_bias \
|
| 104 |
+
--norm_type rmsnorm \
|
| 105 |
+
--model_type ddit \
|
| 106 |
+
--ddit_mlp_type swiglu \
|
| 107 |
+
--state_format prob \
|
| 108 |
+
--bridge dirichlet \
|
| 109 |
+
--target_loss hard_ce \
|
| 110 |
+
--loss_t_weight_mode none \
|
| 111 |
+
--loss_t_min_weight 0.0 \
|
| 112 |
+
--rollout_train_prob 0.50 \
|
| 113 |
+
--rollout_train_time_mode sampled_path \
|
| 114 |
+
--rollout_train_steps 1 \
|
| 115 |
+
--rollout_train_steps_min 1 \
|
| 116 |
+
--rollout_train_infer_steps 1 \
|
| 117 |
+
--rollout_train_s_dist uniform \
|
| 118 |
+
--rollout_train_s_min_frac 0.0 \
|
| 119 |
+
--rollout_train_s_max_frac 0.25 \
|
| 120 |
+
--rollout_train_temp 1.0 \
|
| 121 |
+
--rollout_train_max_gamma 1.0 \
|
| 122 |
+
--rollout_train_corrupt_only \
|
| 123 |
+
--rollout_train_samplewise \
|
| 124 |
+
--rollout_train_selected_only \
|
| 125 |
+
--no-rollout_train_compute_always \
|
| 126 |
+
--rollout_train_keep_grad \
|
| 127 |
+
--rollout_train_sync_t \
|
| 128 |
+
--target_prob 1.0 \
|
| 129 |
+
--min_t 0.0 \
|
| 130 |
+
--max_t 1.0 \
|
| 131 |
+
--t_sampling_mode uniform \
|
| 132 |
+
--t_sampling_logit_mean -1.5 \
|
| 133 |
+
--t_sampling_logit_std 0.8 \
|
| 134 |
+
--t_sampling_eps 1e-4 \
|
| 135 |
+
--dual_t \
|
| 136 |
+
--corrupt_t_mode same \
|
| 137 |
+
--corrupt_min_t 0.0 \
|
| 138 |
+
--corrupt_max_t 1.0 \
|
| 139 |
+
--min_mask_ratio 1.0 \
|
| 140 |
+
--max_mask_ratio 1.0 \
|
| 141 |
+
--mask_mixture_original_prob 0.0 \
|
| 142 |
+
--mask_mixture_lowk_prob 0.0 \
|
| 143 |
+
--mask_mixture_lowcorrupt_prob 0.0 \
|
| 144 |
+
--mask_mixture_block_prob 0.0 \
|
| 145 |
+
--mask_mixture_all_prob 1.0 \
|
| 146 |
+
--wrong_token_replace_prob 1.0 \
|
| 147 |
+
--wrong_token_schedule linear_t \
|
| 148 |
+
--wrong_token_exp_k 1.0 \
|
| 149 |
+
--dirichlet_concentration_min 1.0 \
|
| 150 |
+
--dirichlet_concentration_max 1024 \
|
| 151 |
+
--dirichlet_endpoint_mode categorical_dual_t \
|
| 152 |
+
--dirichlet_semantic_t_mode same \
|
| 153 |
+
--dirichlet_semantic_t_value 0.0 \
|
| 154 |
+
--categorical_wrong_from_full_vocab \
|
| 155 |
+
--simplex_bridge_sampler dirichlet \
|
| 156 |
+
--eps 1e-8 \
|
| 157 |
+
--infer_steps 1024 \
|
| 158 |
+
--decode_damping 1.0 \
|
| 159 |
+
--max_gamma 1.0 \
|
| 160 |
+
--decode_solver flowmap \
|
| 161 |
+
--noise_init logistic_normal \
|
| 162 |
+
--bridge_noise_init logistic_normal \
|
| 163 |
+
--noise_sigma -1 \
|
| 164 |
+
--allow_tf32 \
|
| 165 |
+
--activation_checkpointing \
|
| 166 |
+
--activation_checkpoint_scope mlp \
|
| 167 |
+
--ddp_gradient_as_bucket_view \
|
| 168 |
+
2>&1 | tee -a "${LOG_FILE}"
|
LTA_openwebtext_dualt/scripts/make_duo_integral_cache.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
import argparse
|
| 5 |
+
import pickle
|
| 6 |
+
import time
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
|
| 9 |
+
import numpy as np
|
| 10 |
+
from scipy.integrate import quad
|
| 11 |
+
from scipy.stats import norm
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def _discrete_prob_map(gamma_t: float, vocab_size: int):
|
| 15 |
+
snr_sqrt = np.exp(-gamma_t / 2)
|
| 16 |
+
|
| 17 |
+
def value(x):
|
| 18 |
+
cdf = norm.cdf(x, scale=1) ** (vocab_size - 1)
|
| 19 |
+
pdf = norm.pdf(x, loc=snr_sqrt, scale=1)
|
| 20 |
+
return pdf * cdf
|
| 21 |
+
|
| 22 |
+
return value
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def _discrete_prob_grad(gamma_t: float, vocab_size: int):
|
| 26 |
+
snr_sqrt = np.exp(-gamma_t / 2)
|
| 27 |
+
|
| 28 |
+
def value(x):
|
| 29 |
+
coef = -0.5 * snr_sqrt * (x - snr_sqrt)
|
| 30 |
+
cdf = norm.cdf(x, scale=1) ** (vocab_size - 1)
|
| 31 |
+
pdf = norm.pdf(x, loc=snr_sqrt, scale=1)
|
| 32 |
+
return coef * pdf * cdf
|
| 33 |
+
|
| 34 |
+
return value
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def main() -> None:
|
| 38 |
+
p = argparse.ArgumentParser()
|
| 39 |
+
p.add_argument("--vocab_size", type=int, required=True)
|
| 40 |
+
p.add_argument("--log10_num_points", type=int, default=5)
|
| 41 |
+
p.add_argument("--output", required=True)
|
| 42 |
+
p.add_argument("--gamma_min", type=float, default=-5.0)
|
| 43 |
+
p.add_argument("--gamma_max", type=float, default=-1.0)
|
| 44 |
+
args = p.parse_args()
|
| 45 |
+
|
| 46 |
+
output = Path(args.output)
|
| 47 |
+
output.parent.mkdir(parents=True, exist_ok=True)
|
| 48 |
+
num_points = 10 ** int(args.log10_num_points)
|
| 49 |
+
gammas = np.linspace(args.gamma_min, args.gamma_max, num_points)
|
| 50 |
+
pt = []
|
| 51 |
+
grad_pt = []
|
| 52 |
+
start = time.time()
|
| 53 |
+
for i, gamma in enumerate(gammas, start=1):
|
| 54 |
+
val, _ = quad(_discrete_prob_map(float(gamma), args.vocab_size), -np.inf, np.inf)
|
| 55 |
+
grad, _ = quad(_discrete_prob_grad(float(gamma), args.vocab_size), -np.inf, np.inf)
|
| 56 |
+
pt.append(val)
|
| 57 |
+
grad_pt.append(grad)
|
| 58 |
+
if i % 100 == 0 or i == num_points:
|
| 59 |
+
print(f"{100 * i / num_points:.1f}% completed elapsed={(time.time() - start) / 60:.2f}m", flush=True)
|
| 60 |
+
|
| 61 |
+
payload = {
|
| 62 |
+
"vocab_size": args.vocab_size,
|
| 63 |
+
"gamma_min": args.gamma_min,
|
| 64 |
+
"gamma_max": args.gamma_max,
|
| 65 |
+
"num_points": num_points,
|
| 66 |
+
"pt": np.asarray(pt),
|
| 67 |
+
"grad_pt": np.asarray(grad_pt),
|
| 68 |
+
}
|
| 69 |
+
tmp = output.with_suffix(output.suffix + ".tmp")
|
| 70 |
+
with tmp.open("wb") as f:
|
| 71 |
+
pickle.dump(payload, f)
|
| 72 |
+
tmp.replace(output)
|
| 73 |
+
print(f"wrote {output}", flush=True)
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
if __name__ == "__main__":
|
| 77 |
+
main()
|
LTA_openwebtext_dualt/scripts/prepare_elf_wmt14_deen_t5.sh
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 6 |
+
|
| 7 |
+
DATA_ROOT="${DATA_ROOT:-/e2e-data/evad-tech-vla/wanghan58/data/small_benchmarks/elf}"
|
| 8 |
+
CACHE_DIR="${CACHE_DIR:-/e2e-data/evad-tech-vla/wanghan58/data/hf_cache}"
|
| 9 |
+
mkdir -p "${DATA_ROOT}" "${CACHE_DIR}"
|
| 10 |
+
|
| 11 |
+
python - <<'PY'
|
| 12 |
+
from pathlib import Path
|
| 13 |
+
from datasets import load_from_disk
|
| 14 |
+
from huggingface_hub import snapshot_download
|
| 15 |
+
|
| 16 |
+
data_root = Path(__import__("os").environ["DATA_ROOT"])
|
| 17 |
+
cache_dir = __import__("os").environ["CACHE_DIR"]
|
| 18 |
+
repos = {
|
| 19 |
+
"embedded-language-flows/wmt14_de-en_train_t5": data_root / "wmt14_de-en_train_t5",
|
| 20 |
+
"embedded-language-flows/wmt14_de-en_validation_t5": data_root / "wmt14_de-en_validation_t5",
|
| 21 |
+
}
|
| 22 |
+
for repo, out_dir in repos.items():
|
| 23 |
+
if out_dir.exists():
|
| 24 |
+
print(f"[skip] {out_dir} already exists")
|
| 25 |
+
continue
|
| 26 |
+
print(f"[download] {repo}")
|
| 27 |
+
snap = snapshot_download(repo_id=repo, repo_type="dataset", cache_dir=cache_dir)
|
| 28 |
+
ds = load_from_disk(snap)
|
| 29 |
+
print(f"[save] {repo}: rows={len(ds)} -> {out_dir}")
|
| 30 |
+
ds.save_to_disk(str(out_dir))
|
| 31 |
+
print("[done]")
|
| 32 |
+
PY
|
LTA_openwebtext_dualt/scripts/run_lta_lm1b_bert_absrope_time4_dirichlet_len128_C1_to_1024_4gpu_1m_mask1_sameT_save1k.sh
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
|
| 6 |
+
# Apple-to-apple control for:
|
| 7 |
+
# run_lta_owt_bert_absrope_time4_dirichlet_len128_C1_to_1024_4gpu_1m_mask1_sameT_save1k.sh
|
| 8 |
+
#
|
| 9 |
+
# Only swap the training data to LM1B. Keep:
|
| 10 |
+
# BERT tokenizer, [CLS]/[SEP] wrapping, max_len=128, 4 GPUs,
|
| 11 |
+
# ddit_elf + 4 time tokens + RoPE + learned abs position embeddings,
|
| 12 |
+
# C=1->1024, mask_ratio=1.0, corrupt/model t shared,
|
| 13 |
+
# every-1k checkpoint + dual-line watcher inference.
|
| 14 |
+
|
| 15 |
+
export DATA_PATH="${DATA_PATH:-data/lm1b_train_parquet}"
|
| 16 |
+
export TEXT_COLUMN="${TEXT_COLUMN:-text}"
|
| 17 |
+
export OPENWEBTEXT_SPLIT="${OPENWEBTEXT_SPLIT:-all}"
|
| 18 |
+
export TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/workspace/imagenet_handoff_20260327/nlp_dts_light/assets/distilbert-base-uncased/tokenizer.json}"
|
| 19 |
+
export TOKENIZED_HF=0
|
| 20 |
+
export WRAP_MODE="${WRAP_MODE:-stream}"
|
| 21 |
+
|
| 22 |
+
export DATE_TAG="${DATE_TAG:-$(date +%Y%m%d)}"
|
| 23 |
+
export RUN_NAME="${RUN_NAME:-lta_lm1b_bert_absrope_time4_dirichlet_len128_C1_to_1024_mask1_sameT_gbs512_b32_4gpu_1m_save1k_${DATE_TAG}}"
|
| 24 |
+
|
| 25 |
+
export MASTER_PORT="${MASTER_PORT:-32761}"
|
| 26 |
+
export WATCH_LOG_DIR="${WATCH_LOG_DIR:-logs/lm1b_bert_absrope_time4_len128_C1_to_1024_mask1_sameT_every1k_dualline_watch}"
|
| 27 |
+
export WATCH_OUT_BASE="${WATCH_OUT_BASE:-docs/lta_samples/metrics_${DATE_TAG}/lm1b_bert_absrope_time4_len128_C1_to_1024_mask1_sameT_every1k_dualline_dirres_c1_1024_n128/${RUN_NAME}}"
|
| 28 |
+
|
| 29 |
+
bash scripts/run_lta_owt_bert_absrope_time4_dirichlet_len128_C1_to_1024_4gpu_1m_mask1_sameT_save1k.sh
|
LTA_openwebtext_dualt/scripts/run_lta_owt_dirichlet_len1024_Cv_to_2v_4gpu_abspos_specialloss_watch.sh
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
|
| 6 |
+
export CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0,1,2,3}"
|
| 7 |
+
export NPROC_PER_NODE="${NPROC_PER_NODE:-4}"
|
| 8 |
+
export MASTER_PORT="${MASTER_PORT:-32674}"
|
| 9 |
+
|
| 10 |
+
export GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 11 |
+
export PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-4}"
|
| 12 |
+
export TOTAL_STEPS="${TOTAL_STEPS:-20000}"
|
| 13 |
+
export WARMUP_STEPS="${WARMUP_STEPS:-2500}"
|
| 14 |
+
export SAVE_EVERY="${SAVE_EVERY:-1000}"
|
| 15 |
+
export LATEST_EVERY="${LATEST_EVERY:-1000}"
|
| 16 |
+
export LOG_EVERY="${LOG_EVERY:-100}"
|
| 17 |
+
|
| 18 |
+
export MAX_LEN="${MAX_LEN:-1024}"
|
| 19 |
+
export VOCAB_SIZE="${VOCAB_SIZE:-30522}"
|
| 20 |
+
export CMIN="${CMIN:-${VOCAB_SIZE}}"
|
| 21 |
+
export CMAX="${CMAX:-61044}"
|
| 22 |
+
|
| 23 |
+
export ABS_POS_EMBED="${ABS_POS_EMBED:-1}"
|
| 24 |
+
export FORCE_SPECIAL_CORRUPT_TOKEN_IDS="${FORCE_SPECIAL_CORRUPT_TOKEN_IDS:-101,102}"
|
| 25 |
+
export SPECIAL_LOSS_TOKEN_IDS="${SPECIAL_LOSS_TOKEN_IDS:-101,102}"
|
| 26 |
+
export SPECIAL_LOSS_WEIGHT="${SPECIAL_LOSS_WEIGHT:-16.0}"
|
| 27 |
+
# Keep Bernoulli wrong input endpoints for specials in the first causal test.
|
| 28 |
+
export SPECIAL_ENDPOINT_GOLD_TOKEN_IDS="${SPECIAL_ENDPOINT_GOLD_TOKEN_IDS:-}"
|
| 29 |
+
|
| 30 |
+
export MIN_MASK_RATIO="${MIN_MASK_RATIO:-0.1}"
|
| 31 |
+
export MAX_MASK_RATIO="${MAX_MASK_RATIO:-1.0}"
|
| 32 |
+
export CATEGORICAL_WRONG_PROB_FLOOR="${CATEGORICAL_WRONG_PROB_FLOOR:-0.0}"
|
| 33 |
+
|
| 34 |
+
export WATCH_ENABLED="${WATCH_ENABLED:-1}"
|
| 35 |
+
export WATCH_CUDA_VISIBLE_DEVICES="${WATCH_CUDA_VISIBLE_DEVICES:-3}"
|
| 36 |
+
export WATCH_STEP_INTERVAL="${WATCH_STEP_INTERVAL:-1000}"
|
| 37 |
+
export WATCH_N_SAMPLES="${WATCH_N_SAMPLES:-128}"
|
| 38 |
+
|
| 39 |
+
DATE_TAG="${DATE_TAG:-$(date +%Y%m%d)}"
|
| 40 |
+
export RUN_NAME="${RUN_NAME:-lta_owt_dirichlet_len1024_Cv_to_2v_gbs512_4gpu_abspos_specialloss16_save1k_gumbelwatch_${DATE_TAG}}"
|
| 41 |
+
|
| 42 |
+
bash scripts/run_lta_owt_dirichlet_len1024_Cv_to_2v_8gpu_save1k_with_gumbel_watch.sh
|
LTA_openwebtext_dualt/scripts/run_lta_owt_dirichlet_len1024_Cv_to_2v_8gpu_save1k_with_gumbel_watch.sh
ADDED
|
@@ -0,0 +1,404 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
|
| 6 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 7 |
+
export TOKENIZERS_PARALLELISM=false
|
| 8 |
+
export PYTHONUNBUFFERED=1
|
| 9 |
+
export NCCL_DEBUG="${NCCL_DEBUG:-WARN}"
|
| 10 |
+
export TORCH_DISTRIBUTED_TIMEOUT="${TORCH_DISTRIBUTED_TIMEOUT:-3600}"
|
| 11 |
+
|
| 12 |
+
DATE_TAG="${DATE_TAG:-$(date +%Y%m%d)}"
|
| 13 |
+
MAX_LEN="${MAX_LEN:-1024}"
|
| 14 |
+
VOCAB_SIZE="${VOCAB_SIZE:-30522}"
|
| 15 |
+
CMIN="${CMIN:-${VOCAB_SIZE}}"
|
| 16 |
+
CMAX="${CMAX:-61044}"
|
| 17 |
+
|
| 18 |
+
RUN_NAME="${RUN_NAME:-lta_owt_dirichlet_len${MAX_LEN}_Cv_to_2v_gbs512_8gpu_20k_save1k_gumbelwatch_${DATE_TAG}}"
|
| 19 |
+
SAVE_DIR="${SAVE_DIR:-runs/${RUN_NAME}}"
|
| 20 |
+
LOG_FILE="${LOG_FILE:-logs/${RUN_NAME}.log}"
|
| 21 |
+
|
| 22 |
+
DATA_PATH="${DATA_PATH:-/e2e-data/evad-tech-vla/wanghan58/data/small_benchmarks/langflow_2604_11748/openwebtext}"
|
| 23 |
+
TEXT_COLUMN="${TEXT_COLUMN:-text}"
|
| 24 |
+
OPENWEBTEXT_SPLIT="${OPENWEBTEXT_SPLIT:-train_minus_100k}"
|
| 25 |
+
TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/workspace/imagenet_handoff_20260327/nlp_dts_light/assets/distilbert-base-uncased/tokenizer.json}"
|
| 26 |
+
SCORER="${SCORER:-/e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-large-standard}"
|
| 27 |
+
TOKENIZED_HF="${TOKENIZED_HF:-0}"
|
| 28 |
+
TOKENIZED_PAD_TOKEN="${TOKENIZED_PAD_TOKEN:-pad}"
|
| 29 |
+
TOKENIZED_PREPEND_BOS="${TOKENIZED_PREPEND_BOS:-0}"
|
| 30 |
+
TOKENIZED_APPEND_EOS="${TOKENIZED_APPEND_EOS:-0}"
|
| 31 |
+
TOKENIZED_STRIP_EDGE_SPECIALS="${TOKENIZED_STRIP_EDGE_SPECIALS:-0}"
|
| 32 |
+
|
| 33 |
+
CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0,1,2,3,4,5,6,7}"
|
| 34 |
+
NNODES="${NNODES:-1}"
|
| 35 |
+
NPROC_PER_NODE="${NPROC_PER_NODE:-8}"
|
| 36 |
+
NODE_RANK="${NODE_RANK:-0}"
|
| 37 |
+
MASTER_ADDR="${MASTER_ADDR:-127.0.0.1}"
|
| 38 |
+
MASTER_PORT="${MASTER_PORT:-32681}"
|
| 39 |
+
|
| 40 |
+
GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 41 |
+
PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-32}"
|
| 42 |
+
TOTAL_STEPS="${TOTAL_STEPS:-20000}"
|
| 43 |
+
WARMUP_STEPS="${WARMUP_STEPS:-2500}"
|
| 44 |
+
LOG_EVERY="${LOG_EVERY:-100}"
|
| 45 |
+
SAVE_EVERY="${SAVE_EVERY:-1000}"
|
| 46 |
+
LATEST_EVERY="${LATEST_EVERY:-1000}"
|
| 47 |
+
EVAL_EVERY="${EVAL_EVERY:-0}"
|
| 48 |
+
NUM_WORKERS="${NUM_WORKERS:-0}"
|
| 49 |
+
WRAP_MODE="${WRAP_MODE:-stream}"
|
| 50 |
+
WRAP_RECORD_BUFFER_SIZE="${WRAP_RECORD_BUFFER_SIZE:-200}"
|
| 51 |
+
ALLOW_EXISTING_SAVE_DIR="${ALLOW_EXISTING_SAVE_DIR:-0}"
|
| 52 |
+
RESUME_PATH="${RESUME_PATH:-}"
|
| 53 |
+
|
| 54 |
+
MIN_MASK_RATIO="${MIN_MASK_RATIO:-0.1}"
|
| 55 |
+
MAX_MASK_RATIO="${MAX_MASK_RATIO:-1.0}"
|
| 56 |
+
CATEGORICAL_WRONG_PROB_FLOOR="${CATEGORICAL_WRONG_PROB_FLOOR:-0.0}"
|
| 57 |
+
CORRUPT_T_MODE="${CORRUPT_T_MODE:-independent}"
|
| 58 |
+
ABS_POS_EMBED="${ABS_POS_EMBED:-0}"
|
| 59 |
+
MODEL_TYPE="${MODEL_TYPE:-ddit}"
|
| 60 |
+
ELF_NUM_TIME_TOKENS="${ELF_NUM_TIME_TOKENS:-4}"
|
| 61 |
+
ELF_NUM_MODEL_MODE_TOKENS="${ELF_NUM_MODEL_MODE_TOKENS:-0}"
|
| 62 |
+
QK_NORM="${QK_NORM:-1}"
|
| 63 |
+
FORCE_SPECIAL_CORRUPT_TOKEN_IDS="${FORCE_SPECIAL_CORRUPT_TOKEN_IDS:-}"
|
| 64 |
+
SPECIAL_ENDPOINT_GOLD_TOKEN_IDS="${SPECIAL_ENDPOINT_GOLD_TOKEN_IDS:-}"
|
| 65 |
+
SPECIAL_LOSS_TOKEN_IDS="${SPECIAL_LOSS_TOKEN_IDS:-}"
|
| 66 |
+
SPECIAL_LOSS_WEIGHT="${SPECIAL_LOSS_WEIGHT:-1.0}"
|
| 67 |
+
|
| 68 |
+
WATCH_ENABLED="${WATCH_ENABLED:-0}"
|
| 69 |
+
WATCH_CUDA_VISIBLE_DEVICES="${WATCH_CUDA_VISIBLE_DEVICES:-7}"
|
| 70 |
+
WATCH_STEP_INTERVAL="${WATCH_STEP_INTERVAL:-1000}"
|
| 71 |
+
WATCH_SLEEP_SECONDS="${WATCH_SLEEP_SECONDS:-30}"
|
| 72 |
+
WATCH_N_SAMPLES="${WATCH_N_SAMPLES:-128}"
|
| 73 |
+
WATCH_STEPS="${WATCH_STEPS:-128}"
|
| 74 |
+
WATCH_ENDPOINT_TEMP="${WATCH_ENDPOINT_TEMP:-1.45}"
|
| 75 |
+
WATCH_ENDPOINT_TOP_P="${WATCH_ENDPOINT_TOP_P:-0.95}"
|
| 76 |
+
WATCH_GUMBEL_TAU_START="${WATCH_GUMBEL_TAU_START:-1.0}"
|
| 77 |
+
WATCH_GUMBEL_TAU_END="${WATCH_GUMBEL_TAU_END:-0.2}"
|
| 78 |
+
WATCH_DECODE_BATCH="${WATCH_DECODE_BATCH:-2}"
|
| 79 |
+
WATCH_SCORE_BATCH="${WATCH_SCORE_BATCH:-1}"
|
| 80 |
+
WATCH_SCORE_MAX_LENGTH="${WATCH_SCORE_MAX_LENGTH:-1024}"
|
| 81 |
+
WATCH_DECODE_MODE="${WATCH_DECODE_MODE:-sde_gumbel}"
|
| 82 |
+
WATCH_DUAL_SEMANTIC_POWER="${WATCH_DUAL_SEMANTIC_POWER:-1.5}"
|
| 83 |
+
WATCH_DUAL_EARLY_TEMP="${WATCH_DUAL_EARLY_TEMP:-2.8}"
|
| 84 |
+
WATCH_DUAL_LATE_TEMP="${WATCH_DUAL_LATE_TEMP:-1.45}"
|
| 85 |
+
WATCH_DUAL_TEMP_END="${WATCH_DUAL_TEMP_END:-0.55}"
|
| 86 |
+
WATCH_DUAL_TEMP_POWER="${WATCH_DUAL_TEMP_POWER:-1.5}"
|
| 87 |
+
WATCH_OUT_BASE="${WATCH_OUT_BASE:-docs/lta_samples/metrics_${DATE_TAG}/owt_dirichlet_len${MAX_LEN}_Cv_to_2v_every1k_sde_gumbel_topp${WATCH_ENDPOINT_TOP_P//./p}_tau${WATCH_GUMBEL_TAU_START//./p}_to_${WATCH_GUMBEL_TAU_END//./p}_blend_c${CMIN}_${CMAX}_n${WATCH_N_SAMPLES}/${RUN_NAME}}"
|
| 88 |
+
WATCH_LOG_DIR="${WATCH_LOG_DIR:-logs/owt_dirichlet_len${MAX_LEN}_Cv_to_2v_gumbel_sde_watch}"
|
| 89 |
+
WATCH_SCRIPT="${WATCH_SCRIPT:-logs/${RUN_NAME}_watcher.sh}"
|
| 90 |
+
WATCH_LOG="${WATCH_LOG:-logs/${RUN_NAME}_watcher.log}"
|
| 91 |
+
WATCH_PID_FILE="${WATCH_PID_FILE:-logs/${RUN_NAME}_watcher.pid}"
|
| 92 |
+
|
| 93 |
+
if [[ -f "${SAVE_DIR}/args.json" && -z "${RESUME_PATH}" && "${ALLOW_EXISTING_SAVE_DIR}" != "1" ]]; then
|
| 94 |
+
echo "Refusing to start because SAVE_DIR already contains args.json: ${SAVE_DIR}" >&2
|
| 95 |
+
echo "Set RESUME_PATH, use a new RUN_NAME/SAVE_DIR, or ALLOW_EXISTING_SAVE_DIR=1." >&2
|
| 96 |
+
exit 2
|
| 97 |
+
fi
|
| 98 |
+
|
| 99 |
+
mkdir -p logs runs "${SAVE_DIR}" "${WATCH_LOG_DIR}" "${WATCH_OUT_BASE}"
|
| 100 |
+
|
| 101 |
+
RESUME_ARGS=()
|
| 102 |
+
if [[ -n "${RESUME_PATH}" ]]; then
|
| 103 |
+
RESUME_ARGS+=(--resume_path "${RESUME_PATH}")
|
| 104 |
+
fi
|
| 105 |
+
|
| 106 |
+
TEXT_COLUMN_ARGS=()
|
| 107 |
+
if [[ -n "${TEXT_COLUMN}" ]]; then
|
| 108 |
+
TEXT_COLUMN_ARGS+=(--text_column "${TEXT_COLUMN}")
|
| 109 |
+
fi
|
| 110 |
+
|
| 111 |
+
OPENWEBTEXT_ARGS=(--openwebtext_split "${OPENWEBTEXT_SPLIT}")
|
| 112 |
+
WRAP_ARGS=(--wrap --wrap_mode "${WRAP_MODE}" --wrap_record_buffer_size "${WRAP_RECORD_BUFFER_SIZE}")
|
| 113 |
+
TOKENIZED_ARGS=()
|
| 114 |
+
DATA_MODE_LABEL="raw_wrap_${WRAP_MODE}"
|
| 115 |
+
if [[ "${TOKENIZED_HF}" == "1" || "${TOKENIZED_HF}" == "true" || "${TOKENIZED_HF}" == "True" ]]; then
|
| 116 |
+
TEXT_COLUMN_ARGS=()
|
| 117 |
+
OPENWEBTEXT_ARGS=()
|
| 118 |
+
WRAP_ARGS=()
|
| 119 |
+
TOKENIZED_ARGS=(--tokenized_hf --tokenized_pad_token "${TOKENIZED_PAD_TOKEN}")
|
| 120 |
+
if [[ "${TOKENIZED_PREPEND_BOS}" == "1" || "${TOKENIZED_PREPEND_BOS}" == "true" || "${TOKENIZED_PREPEND_BOS}" == "True" ]]; then
|
| 121 |
+
TOKENIZED_ARGS+=(--tokenized_prepend_bos)
|
| 122 |
+
fi
|
| 123 |
+
if [[ "${TOKENIZED_APPEND_EOS}" == "1" || "${TOKENIZED_APPEND_EOS}" == "true" || "${TOKENIZED_APPEND_EOS}" == "True" ]]; then
|
| 124 |
+
TOKENIZED_ARGS+=(--tokenized_append_eos)
|
| 125 |
+
fi
|
| 126 |
+
if [[ "${TOKENIZED_STRIP_EDGE_SPECIALS}" == "1" || "${TOKENIZED_STRIP_EDGE_SPECIALS}" == "true" || "${TOKENIZED_STRIP_EDGE_SPECIALS}" == "True" ]]; then
|
| 127 |
+
TOKENIZED_ARGS+=(--tokenized_strip_edge_specials)
|
| 128 |
+
fi
|
| 129 |
+
DATA_MODE_LABEL="tokenized_hf_pad_${TOKENIZED_PAD_TOKEN}"
|
| 130 |
+
fi
|
| 131 |
+
|
| 132 |
+
ABS_POS_ARGS=()
|
| 133 |
+
if [[ "${ABS_POS_EMBED}" == "1" || "${ABS_POS_EMBED}" == "true" || "${ABS_POS_EMBED}" == "True" ]]; then
|
| 134 |
+
ABS_POS_ARGS+=(--abs_pos_embed)
|
| 135 |
+
fi
|
| 136 |
+
|
| 137 |
+
QK_NORM_ARGS=(--qk_norm)
|
| 138 |
+
if [[ "${QK_NORM}" == "0" || "${QK_NORM}" == "false" || "${QK_NORM}" == "False" ]]; then
|
| 139 |
+
QK_NORM_ARGS=(--no-qk_norm)
|
| 140 |
+
fi
|
| 141 |
+
|
| 142 |
+
SPECIAL_ARGS=()
|
| 143 |
+
if [[ -n "${FORCE_SPECIAL_CORRUPT_TOKEN_IDS}" ]]; then
|
| 144 |
+
SPECIAL_ARGS+=(--force_special_corrupt_token_ids "${FORCE_SPECIAL_CORRUPT_TOKEN_IDS}")
|
| 145 |
+
fi
|
| 146 |
+
if [[ -n "${SPECIAL_ENDPOINT_GOLD_TOKEN_IDS}" ]]; then
|
| 147 |
+
SPECIAL_ARGS+=(--special_endpoint_gold_token_ids "${SPECIAL_ENDPOINT_GOLD_TOKEN_IDS}")
|
| 148 |
+
fi
|
| 149 |
+
if [[ -n "${SPECIAL_LOSS_TOKEN_IDS}" ]]; then
|
| 150 |
+
SPECIAL_ARGS+=(--special_loss_token_ids "${SPECIAL_LOSS_TOKEN_IDS}" --special_loss_weight "${SPECIAL_LOSS_WEIGHT}")
|
| 151 |
+
fi
|
| 152 |
+
|
| 153 |
+
write_watcher() {
|
| 154 |
+
cat > "${WATCH_SCRIPT}" <<'WATCH_EOF'
|
| 155 |
+
#!/usr/bin/env bash
|
| 156 |
+
set -euo pipefail
|
| 157 |
+
|
| 158 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 159 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 160 |
+
export TOKENIZERS_PARALLELISM=false
|
| 161 |
+
export PYTHONUNBUFFERED=1
|
| 162 |
+
|
| 163 |
+
: "${RUN_DIR:?RUN_DIR is required}"
|
| 164 |
+
: "${OUT_BASE:?OUT_BASE is required}"
|
| 165 |
+
: "${LOG_DIR:?LOG_DIR is required}"
|
| 166 |
+
: "${TOKENIZER_PATH:?TOKENIZER_PATH is required}"
|
| 167 |
+
: "${SCORER:?SCORER is required}"
|
| 168 |
+
|
| 169 |
+
RUN_STEM="$(basename "${RUN_DIR}")"
|
| 170 |
+
TEMP_TAG="${ENDPOINT_TEMP//./p}"
|
| 171 |
+
PROCESSED_FILE="${LOG_DIR}/processed_${RUN_STEM}_steps${STEPS}_c${CMIN}_${CMAX}_gumbel_t${TEMP_TAG}_n${N_SAMPLES}.txt"
|
| 172 |
+
|
| 173 |
+
mkdir -p "${OUT_BASE}" "${LOG_DIR}"
|
| 174 |
+
touch "${PROCESSED_FILE}"
|
| 175 |
+
|
| 176 |
+
echo "[watch-gumbel] run_dir=${RUN_DIR}"
|
| 177 |
+
echo "[watch-gumbel] out_base=${OUT_BASE}"
|
| 178 |
+
echo "[watch-gumbel] interval=${STEP_INTERVAL} max_len=${MAX_LEN} steps=${STEPS} c=${CMIN}->${CMAX} decode_mode=${DECODE_MODE:-sde_gumbel} temp=${ENDPOINT_TEMP} top_p=${ENDPOINT_TOP_P} tau=${GUMBEL_TAU_START}->${GUMBEL_TAU_END} n=${N_SAMPLES}"
|
| 179 |
+
|
| 180 |
+
while true; do
|
| 181 |
+
shopt -s nullglob
|
| 182 |
+
ckpts=("${RUN_DIR}"/step_*.pt)
|
| 183 |
+
shopt -u nullglob
|
| 184 |
+
|
| 185 |
+
if (( ${#ckpts[@]} == 0 )); then
|
| 186 |
+
echo "[watch-gumbel] $(date +%F_%T) no ckpt yet"
|
| 187 |
+
sleep "${SLEEP_SECONDS}"
|
| 188 |
+
continue
|
| 189 |
+
fi
|
| 190 |
+
|
| 191 |
+
printf "%s\n" "${ckpts[@]}" | sort | while read -r ckpt; do
|
| 192 |
+
base="$(basename "${ckpt}")"
|
| 193 |
+
step="${base#step_}"
|
| 194 |
+
step="${step%.pt}"
|
| 195 |
+
step_num=$((10#${step}))
|
| 196 |
+
if (( step_num % STEP_INTERVAL != 0 )); then
|
| 197 |
+
continue
|
| 198 |
+
fi
|
| 199 |
+
if grep -Fxq "${ckpt}" "${PROCESSED_FILE}"; then
|
| 200 |
+
continue
|
| 201 |
+
fi
|
| 202 |
+
|
| 203 |
+
out_dir="${OUT_BASE}/step_${step}"
|
| 204 |
+
log_file="${LOG_DIR}/infer_${RUN_STEM}_step_${step}.log"
|
| 205 |
+
mkdir -p "${out_dir}"
|
| 206 |
+
|
| 207 |
+
echo "[watch-gumbel] $(date +%F_%T) infer ${ckpt} -> ${out_dir}" | tee -a "${log_file}"
|
| 208 |
+
if [[ "${DECODE_MODE:-sde_gumbel}" == "dual_line_probe" ]]; then
|
| 209 |
+
CUDA_VISIBLE_DEVICES="${WATCH_CUDA_VISIBLE_DEVICES}" python scripts/infer_softkl_decode_probe.py \
|
| 210 |
+
--checkpoint "${ckpt}" \
|
| 211 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 212 |
+
--scorer "${SCORER}" \
|
| 213 |
+
--score \
|
| 214 |
+
--out_dir "${out_dir}" \
|
| 215 |
+
--max_lens "${MAX_LEN}" \
|
| 216 |
+
--n_samples "${N_SAMPLES}" \
|
| 217 |
+
--batch_size "${DECODE_BATCH}" \
|
| 218 |
+
--steps "${STEPS}" \
|
| 219 |
+
--decode_rule dual_line_resample \
|
| 220 |
+
--c_min "${CMIN}" \
|
| 221 |
+
--c_max "${CMAX}" \
|
| 222 |
+
--input_noise_dirichlet_concentration "${CMIN}" \
|
| 223 |
+
--anchor_mode state \
|
| 224 |
+
--model_t_mode flow \
|
| 225 |
+
--time_schedule uniform \
|
| 226 |
+
--support_power 1.0 \
|
| 227 |
+
--semantic_power "${DUAL_SEMANTIC_POWER}" \
|
| 228 |
+
--early_temp "${DUAL_EARLY_TEMP}" \
|
| 229 |
+
--late_temp "${DUAL_LATE_TEMP}" \
|
| 230 |
+
--temp_end "${DUAL_TEMP_END}" \
|
| 231 |
+
--temp_power "${DUAL_TEMP_POWER}" \
|
| 232 |
+
--final_from blend \
|
| 233 |
+
--final_decode argmax \
|
| 234 |
+
--seed 20260524 \
|
| 235 |
+
2>&1 | tee -a "${log_file}"
|
| 236 |
+
else
|
| 237 |
+
CUDA_VISIBLE_DEVICES="${WATCH_CUDA_VISIBLE_DEVICES}" python scripts/eval_lm1b_c1024_fullycoupled_sde_genppl.py \
|
| 238 |
+
--checkpoint "${ckpt}" \
|
| 239 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 240 |
+
--scorer "${SCORER}" \
|
| 241 |
+
--out_dir "${out_dir}" \
|
| 242 |
+
--n_samples "${N_SAMPLES}" \
|
| 243 |
+
--max_len "${MAX_LEN}" \
|
| 244 |
+
--steps "${STEPS}" \
|
| 245 |
+
--batch_size "${DECODE_BATCH}" \
|
| 246 |
+
--score_batch "${SCORE_BATCH}" \
|
| 247 |
+
--score_max_length "${SCORE_MAX_LENGTH}" \
|
| 248 |
+
--concentration_min "${CMIN}" \
|
| 249 |
+
--concentration_max "${CMAX}" \
|
| 250 |
+
--endpoint_temp "${ENDPOINT_TEMP}" \
|
| 251 |
+
--endpoint_projection gumbel_softmax \
|
| 252 |
+
--endpoint_top_p "${ENDPOINT_TOP_P}" \
|
| 253 |
+
--gumbel_tau_start "${GUMBEL_TAU_START}" \
|
| 254 |
+
--gumbel_tau_end "${GUMBEL_TAU_END}" \
|
| 255 |
+
--model_t_mode support_t \
|
| 256 |
+
--mean_mode endpoint_only \
|
| 257 |
+
--semantic_power 1.0 \
|
| 258 |
+
--noise_init dirichlet \
|
| 259 |
+
--noise_dirichlet_concentration "${CMIN}" \
|
| 260 |
+
--sde_resample dirichlet \
|
| 261 |
+
--final_from blend_0.5 \
|
| 262 |
+
--seed 20260524 \
|
| 263 |
+
2>&1 | tee -a "${log_file}"
|
| 264 |
+
fi
|
| 265 |
+
|
| 266 |
+
echo "${ckpt}" >> "${PROCESSED_FILE}"
|
| 267 |
+
echo "[watch-gumbel] $(date +%F_%T) done step_${step}" | tee -a "${log_file}"
|
| 268 |
+
done
|
| 269 |
+
|
| 270 |
+
sleep "${SLEEP_SECONDS}"
|
| 271 |
+
done
|
| 272 |
+
WATCH_EOF
|
| 273 |
+
chmod +x "${WATCH_SCRIPT}"
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
start_watcher() {
|
| 277 |
+
if [[ "${WATCH_ENABLED}" != "1" ]]; then
|
| 278 |
+
echo "[launch] watcher disabled"
|
| 279 |
+
return
|
| 280 |
+
fi
|
| 281 |
+
if [[ -f "${WATCH_PID_FILE}" ]]; then
|
| 282 |
+
old_pid="$(cat "${WATCH_PID_FILE}" || true)"
|
| 283 |
+
if [[ -n "${old_pid}" ]] && kill -0 "${old_pid}" 2>/dev/null; then
|
| 284 |
+
echo "[launch] watcher already running pid=${old_pid}"
|
| 285 |
+
return
|
| 286 |
+
fi
|
| 287 |
+
fi
|
| 288 |
+
write_watcher
|
| 289 |
+
nohup env \
|
| 290 |
+
RUN_DIR="${SAVE_DIR}" \
|
| 291 |
+
OUT_BASE="${WATCH_OUT_BASE}" \
|
| 292 |
+
LOG_DIR="${WATCH_LOG_DIR}" \
|
| 293 |
+
TOKENIZER_PATH="${TOKENIZER_PATH}" \
|
| 294 |
+
SCORER="${SCORER}" \
|
| 295 |
+
WATCH_CUDA_VISIBLE_DEVICES="${WATCH_CUDA_VISIBLE_DEVICES}" \
|
| 296 |
+
N_SAMPLES="${WATCH_N_SAMPLES}" \
|
| 297 |
+
MAX_LEN="${MAX_LEN}" \
|
| 298 |
+
STEPS="${WATCH_STEPS}" \
|
| 299 |
+
DECODE_BATCH="${WATCH_DECODE_BATCH}" \
|
| 300 |
+
SCORE_BATCH="${WATCH_SCORE_BATCH}" \
|
| 301 |
+
SCORE_MAX_LENGTH="${WATCH_SCORE_MAX_LENGTH}" \
|
| 302 |
+
DECODE_MODE="${WATCH_DECODE_MODE}" \
|
| 303 |
+
DUAL_SEMANTIC_POWER="${WATCH_DUAL_SEMANTIC_POWER}" \
|
| 304 |
+
DUAL_EARLY_TEMP="${WATCH_DUAL_EARLY_TEMP}" \
|
| 305 |
+
DUAL_LATE_TEMP="${WATCH_DUAL_LATE_TEMP}" \
|
| 306 |
+
DUAL_TEMP_END="${WATCH_DUAL_TEMP_END}" \
|
| 307 |
+
DUAL_TEMP_POWER="${WATCH_DUAL_TEMP_POWER}" \
|
| 308 |
+
CMIN="${CMIN}" \
|
| 309 |
+
CMAX="${CMAX}" \
|
| 310 |
+
ENDPOINT_TEMP="${WATCH_ENDPOINT_TEMP}" \
|
| 311 |
+
ENDPOINT_TOP_P="${WATCH_ENDPOINT_TOP_P}" \
|
| 312 |
+
GUMBEL_TAU_START="${WATCH_GUMBEL_TAU_START}" \
|
| 313 |
+
GUMBEL_TAU_END="${WATCH_GUMBEL_TAU_END}" \
|
| 314 |
+
STEP_INTERVAL="${WATCH_STEP_INTERVAL}" \
|
| 315 |
+
SLEEP_SECONDS="${WATCH_SLEEP_SECONDS}" \
|
| 316 |
+
bash "${WATCH_SCRIPT}" > "${WATCH_LOG}" 2>&1 &
|
| 317 |
+
echo "$!" > "${WATCH_PID_FILE}"
|
| 318 |
+
echo "[launch] watcher pid=$(cat "${WATCH_PID_FILE}") log=${WATCH_LOG}"
|
| 319 |
+
}
|
| 320 |
+
|
| 321 |
+
echo "[launch] run=${RUN_NAME}"
|
| 322 |
+
echo "[launch] data_path=${DATA_PATH} mode=${DATA_MODE_LABEL} split=${OPENWEBTEXT_SPLIT} text_column=${TEXT_COLUMN}"
|
| 323 |
+
echo "[launch] max_len=${MAX_LEN} gbs=${GLOBAL_BATCH_SIZE} per_gpu=${PER_GPU_BATCH_SIZE} total_steps=${TOTAL_STEPS}"
|
| 324 |
+
echo "[launch] dirichlet C=${CMIN}->${CMAX} wrong_floor=${CATEGORICAL_WRONG_PROB_FLOOR} corrupt_t_mode=${CORRUPT_T_MODE}"
|
| 325 |
+
echo "[launch] model_type=${MODEL_TYPE} abs_pos=${ABS_POS_EMBED} elf_time_tokens=${ELF_NUM_TIME_TOKENS} qk_norm=${QK_NORM} force_special_corrupt=${FORCE_SPECIAL_CORRUPT_TOKEN_IDS:-none} special_endpoint_gold=${SPECIAL_ENDPOINT_GOLD_TOKEN_IDS:-none} special_loss=${SPECIAL_LOSS_TOKEN_IDS:-none}x${SPECIAL_LOSS_WEIGHT}"
|
| 326 |
+
start_watcher
|
| 327 |
+
|
| 328 |
+
CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES}" python -m torch.distributed.run \
|
| 329 |
+
--nnodes="${NNODES}" \
|
| 330 |
+
--nproc_per_node="${NPROC_PER_NODE}" \
|
| 331 |
+
--node_rank="${NODE_RANK}" \
|
| 332 |
+
--master_addr="${MASTER_ADDR}" \
|
| 333 |
+
--master_port="${MASTER_PORT}" \
|
| 334 |
+
train.py \
|
| 335 |
+
--data_path "${DATA_PATH}" \
|
| 336 |
+
"${TEXT_COLUMN_ARGS[@]}" \
|
| 337 |
+
"${OPENWEBTEXT_ARGS[@]}" \
|
| 338 |
+
"${TOKENIZED_ARGS[@]}" \
|
| 339 |
+
--detokenizer auto \
|
| 340 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 341 |
+
--save_dir "${SAVE_DIR}" \
|
| 342 |
+
"${WRAP_ARGS[@]}" \
|
| 343 |
+
--max_len "${MAX_LEN}" \
|
| 344 |
+
--batch_size "${PER_GPU_BATCH_SIZE}" \
|
| 345 |
+
--num_workers "${NUM_WORKERS}" \
|
| 346 |
+
--global_batch_size "${GLOBAL_BATCH_SIZE}" \
|
| 347 |
+
--total_steps "${TOTAL_STEPS}" \
|
| 348 |
+
--log_every "${LOG_EVERY}" \
|
| 349 |
+
--eval_every "${EVAL_EVERY}" \
|
| 350 |
+
--save_every "${SAVE_EVERY}" \
|
| 351 |
+
--latest_every "${LATEST_EVERY}" \
|
| 352 |
+
--lr 3e-4 \
|
| 353 |
+
--weight_decay 0 \
|
| 354 |
+
--adam_beta1 0.9 \
|
| 355 |
+
--adam_beta2 0.999 \
|
| 356 |
+
--adam_eps 1e-8 \
|
| 357 |
+
--warmup_steps "${WARMUP_STEPS}" \
|
| 358 |
+
--lr_schedule constant_warmup \
|
| 359 |
+
--grad_clip 1.0 \
|
| 360 |
+
--seed 123 \
|
| 361 |
+
--d_model 768 \
|
| 362 |
+
--cond_dim 128 \
|
| 363 |
+
--n_layers 12 \
|
| 364 |
+
--n_heads 12 \
|
| 365 |
+
--dim_ff 3072 \
|
| 366 |
+
--dropout 0.1 \
|
| 367 |
+
"${ABS_POS_ARGS[@]}" \
|
| 368 |
+
--model_type "${MODEL_TYPE}" \
|
| 369 |
+
--elf_num_time_tokens "${ELF_NUM_TIME_TOKENS}" \
|
| 370 |
+
--elf_num_model_mode_tokens "${ELF_NUM_MODEL_MODE_TOKENS}" \
|
| 371 |
+
"${QK_NORM_ARGS[@]}" \
|
| 372 |
+
--state_format prob \
|
| 373 |
+
--bridge dirichlet \
|
| 374 |
+
--target_loss hard_ce \
|
| 375 |
+
--target_prob 1.0 \
|
| 376 |
+
--min_t 0.0 \
|
| 377 |
+
--max_t 1.0 \
|
| 378 |
+
--dual_t \
|
| 379 |
+
--corrupt_t_mode "${CORRUPT_T_MODE}" \
|
| 380 |
+
--corrupt_min_t 0.0 \
|
| 381 |
+
--corrupt_max_t 1.0 \
|
| 382 |
+
--min_mask_ratio "${MIN_MASK_RATIO}" \
|
| 383 |
+
--max_mask_ratio "${MAX_MASK_RATIO}" \
|
| 384 |
+
--wrong_token_replace_prob 1.0 \
|
| 385 |
+
--wrong_token_schedule linear_t \
|
| 386 |
+
--wrong_token_exp_k 1.0 \
|
| 387 |
+
--categorical_wrong_prob_floor "${CATEGORICAL_WRONG_PROB_FLOOR}" \
|
| 388 |
+
--dirichlet_concentration_min "${CMIN}" \
|
| 389 |
+
--dirichlet_concentration_max "${CMAX}" \
|
| 390 |
+
--dirichlet_endpoint_mode categorical_dual_t \
|
| 391 |
+
--dirichlet_semantic_t_mode same \
|
| 392 |
+
--dirichlet_semantic_t_value 0.0 \
|
| 393 |
+
--categorical_wrong_from_full_vocab \
|
| 394 |
+
--eps 1e-8 \
|
| 395 |
+
--infer_steps 128 \
|
| 396 |
+
--decode_damping 1.0 \
|
| 397 |
+
--max_gamma 1.0 \
|
| 398 |
+
--decode_solver flowmap \
|
| 399 |
+
--noise_init logistic_normal \
|
| 400 |
+
--bridge_noise_init logistic_normal \
|
| 401 |
+
--noise_sigma -1 \
|
| 402 |
+
"${SPECIAL_ARGS[@]}" \
|
| 403 |
+
"${RESUME_ARGS[@]}" \
|
| 404 |
+
--bf16 2>&1 | tee -a "${LOG_FILE}"
|
LTA_openwebtext_dualt/scripts/run_lta_owt_t5_len128_uniform10k_then_lognsr_4gpu.sh
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
|
| 6 |
+
export CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-4,5,6,7}"
|
| 7 |
+
export NPROC_PER_NODE="${NPROC_PER_NODE:-4}"
|
| 8 |
+
export MASTER_PORT="${MASTER_PORT:-39331}"
|
| 9 |
+
export OMP_NUM_THREADS="${OMP_NUM_THREADS:-1}"
|
| 10 |
+
export PYTHONUNBUFFERED=1
|
| 11 |
+
export TOKENIZERS_PARALLELISM=false
|
| 12 |
+
|
| 13 |
+
BASE_RUN_NAME="${BASE_RUN_NAME:-lta_owt_t5_len128_uniform10k_then_lognsr_sde_rollin_4gpu_$(date +%Y%m%d_%H%M%S)}"
|
| 14 |
+
WARMUP_RUN_NAME="${BASE_RUN_NAME}_warmup_uniform_norollin"
|
| 15 |
+
MAIN_RUN_NAME="${BASE_RUN_NAME}_resume_lognsr_sde_rollin"
|
| 16 |
+
|
| 17 |
+
COMMON_ENV=(
|
| 18 |
+
MAX_LEN=128
|
| 19 |
+
GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 20 |
+
PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-32}"
|
| 21 |
+
SAVE_EVERY="${SAVE_EVERY:-1000}"
|
| 22 |
+
LATEST_EVERY="${LATEST_EVERY:-1000}"
|
| 23 |
+
LOG_EVERY="${LOG_EVERY:-100}"
|
| 24 |
+
TARGET_LOSS="${TARGET_LOSS:-hard_ce}"
|
| 25 |
+
MIN_MASK_RATIO=1.0
|
| 26 |
+
MAX_MASK_RATIO=1.0
|
| 27 |
+
MASK_MIXTURE_ALL_PROB=1.0
|
| 28 |
+
)
|
| 29 |
+
|
| 30 |
+
echo "[two-phase] base_run_name=${BASE_RUN_NAME}"
|
| 31 |
+
echo "[two-phase] phase1=${WARMUP_RUN_NAME}: uniform t, no roll-in, 10k steps"
|
| 32 |
+
env "${COMMON_ENV[@]}" \
|
| 33 |
+
RUN_NAME="${WARMUP_RUN_NAME}" \
|
| 34 |
+
TOTAL_STEPS=10000 \
|
| 35 |
+
T_SAMPLING_MODE=uniform \
|
| 36 |
+
ROLLOUT_TRAIN_PROB=0.0 \
|
| 37 |
+
bash scripts/launch_lta_owt_t5_len128_sde_rollin_lognsr_4gpu.sh
|
| 38 |
+
|
| 39 |
+
WARMUP_CKPT="runs/${WARMUP_RUN_NAME}/step_0010000.pt"
|
| 40 |
+
if [[ ! -f "${WARMUP_CKPT}" ]]; then
|
| 41 |
+
echo "[two-phase] missing warmup checkpoint: ${WARMUP_CKPT}" >&2
|
| 42 |
+
exit 1
|
| 43 |
+
fi
|
| 44 |
+
|
| 45 |
+
echo "[two-phase] phase2=${MAIN_RUN_NAME}: resume ${WARMUP_CKPT}, lognsr_gumbel + sde roll-in"
|
| 46 |
+
env "${COMMON_ENV[@]}" \
|
| 47 |
+
RUN_NAME="${MAIN_RUN_NAME}" \
|
| 48 |
+
RESUME_PATH="${WARMUP_CKPT}" \
|
| 49 |
+
TOTAL_STEPS="${TOTAL_STEPS:-1000000}" \
|
| 50 |
+
T_SAMPLING_MODE=lognsr_gumbel \
|
| 51 |
+
T_GUMBEL_LOC="${T_GUMBEL_LOC:-2.2}" \
|
| 52 |
+
T_GUMBEL_SCALE="${T_GUMBEL_SCALE:-0.8}" \
|
| 53 |
+
ROLLOUT_TRAIN_PROB="${ROLLOUT_TRAIN_PROB:-0.50}" \
|
| 54 |
+
ROLLOUT_TRAIN_RULE=dirichlet_resample \
|
| 55 |
+
ROLLOUT_TRAIN_TIME_MODE=sampled_path \
|
| 56 |
+
ROLLOUT_TRAIN_STEPS="${ROLLOUT_TRAIN_STEPS:-3}" \
|
| 57 |
+
ROLLOUT_TRAIN_STEPS_MIN="${ROLLOUT_TRAIN_STEPS_MIN:-0}" \
|
| 58 |
+
ROLLOUT_TRAIN_INFER_STEPS="${ROLLOUT_TRAIN_INFER_STEPS:-1}" \
|
| 59 |
+
ROLLOUT_TRAIN_TEMP="${ROLLOUT_TRAIN_TEMP:-1.0}" \
|
| 60 |
+
bash scripts/launch_lta_owt_t5_len128_sde_rollin_lognsr_4gpu.sh
|
LTA_openwebtext_dualt/scripts/run_train8_ctx1024_sampleds_sweep_4gpu.sh
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
|
| 6 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 7 |
+
export TOKENIZERS_PARALLELISM=false
|
| 8 |
+
export PYTHONUNBUFFERED=1
|
| 9 |
+
|
| 10 |
+
BASE_CACHE="${BASE_CACHE:-/e2e-data/evad-tech-vla/wanghan58/data/small_benchmarks/langflow_2604_11748/openwebtext_lta_cached_chunks}"
|
| 11 |
+
CACHE_PREFIX="${CACHE_PREFIX:-gpt2}"
|
| 12 |
+
CACHE_DIR="${CACHE_DIR:-}"
|
| 13 |
+
TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-standard/tokenizer.json}"
|
| 14 |
+
MAX_LEN="${MAX_LEN:-1024}"
|
| 15 |
+
N_SAMPLES="${N_SAMPLES:-64}"
|
| 16 |
+
INFER_STEPS="${INFER_STEPS:-128}"
|
| 17 |
+
STEP_CHUNK="${STEP_CHUNK:-1000}"
|
| 18 |
+
MAX_TOTAL_STEPS="${MAX_TOTAL_STEPS:-12000}"
|
| 19 |
+
PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE:-128}"
|
| 20 |
+
GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE:-512}"
|
| 21 |
+
LEARNING_RATE="${LEARNING_RATE:-0.002}"
|
| 22 |
+
WEIGHT_DECAY="${WEIGHT_DECAY:-0.1}"
|
| 23 |
+
GROUP_STAMP="${GROUP_STAMP:-$(date +%Y%m%d_%H%M%S)}"
|
| 24 |
+
WAIT_FOR_RUN="${WAIT_FOR_RUN:-}"
|
| 25 |
+
OUT_ROOT="${OUT_ROOT:-docs/lta_samples/metrics_20260517/ctx1024_sampleds_sweep_bs512_ode128_${GROUP_STAMP}}"
|
| 26 |
+
DRIVER_LOG="${DRIVER_LOG:-logs/ctx1024_sampleds_sweep_4gpu/${GROUP_STAMP}.log}"
|
| 27 |
+
CURVE_CSV="${CURVE_CSV:-${OUT_ROOT}/hit_ratio_curve.csv}"
|
| 28 |
+
EVAL_DECODE_RULES="${EVAL_DECODE_RULES:-flowmap}"
|
| 29 |
+
EVAL_C_MAX="${EVAL_C_MAX:-512}"
|
| 30 |
+
EVAL_EARLY_TEMP="${EVAL_EARLY_TEMP:-1.0}"
|
| 31 |
+
EVAL_LATE_TEMP="${EVAL_LATE_TEMP:-1.0}"
|
| 32 |
+
mkdir -p "$(dirname "${DRIVER_LOG}")" "${OUT_ROOT}"
|
| 33 |
+
|
| 34 |
+
if [[ -n "${CACHE_DIR}" ]]; then
|
| 35 |
+
cache="${CACHE_DIR}"
|
| 36 |
+
else
|
| 37 |
+
cache="${BASE_CACHE}/${CACHE_PREFIX}_len${MAX_LEN}_train8_compact_overfit"
|
| 38 |
+
fi
|
| 39 |
+
vocab_size="$(
|
| 40 |
+
python - "$cache" <<'PY'
|
| 41 |
+
import json
|
| 42 |
+
import sys
|
| 43 |
+
from pathlib import Path
|
| 44 |
+
meta = json.loads((Path(sys.argv[1]) / "meta.json").read_text())
|
| 45 |
+
print(int(meta.get("compact_vocab_size", meta.get("vocab_size"))))
|
| 46 |
+
PY
|
| 47 |
+
)"
|
| 48 |
+
|
| 49 |
+
if [[ ! -f "${CURVE_CSV}" ]]; then
|
| 50 |
+
echo "config,decode_rule,run_name,ckpt_step,train_views_seen,train_tokens_seen,token_acc_mean,exact_count,exact_ref_count,exact_ref_hits" > "${CURVE_CSV}"
|
| 51 |
+
fi
|
| 52 |
+
|
| 53 |
+
latest_step() {
|
| 54 |
+
local run_name="$1"
|
| 55 |
+
python - "$run_name" <<'PY'
|
| 56 |
+
import re
|
| 57 |
+
import sys
|
| 58 |
+
from pathlib import Path
|
| 59 |
+
run = Path("runs") / sys.argv[1]
|
| 60 |
+
steps = []
|
| 61 |
+
for path in run.glob("step_*.pt"):
|
| 62 |
+
m = re.search(r"step_(\d+)\.pt$", path.name)
|
| 63 |
+
if m:
|
| 64 |
+
steps.append(int(m.group(1)))
|
| 65 |
+
print(max(steps) if steps else 0)
|
| 66 |
+
PY
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
free_port() {
|
| 70 |
+
python - <<'PY'
|
| 71 |
+
import socket
|
| 72 |
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
| 73 |
+
s.bind(("127.0.0.1", 0))
|
| 74 |
+
print(s.getsockname()[1])
|
| 75 |
+
PY
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
eval_latest() {
|
| 79 |
+
local config="$1"
|
| 80 |
+
local run_name="$2"
|
| 81 |
+
local target_step="$3"
|
| 82 |
+
IFS=',' read -r -a decode_rules <<<"${EVAL_DECODE_RULES}"
|
| 83 |
+
for decode_rule in "${decode_rules[@]}"; do
|
| 84 |
+
decode_rule="$(echo "${decode_rule}" | xargs)"
|
| 85 |
+
[[ -n "${decode_rule}" ]] || continue
|
| 86 |
+
local out_dir="${OUT_ROOT}/${config}/step_${target_step}/${decode_rule}_c${EVAL_C_MAX}"
|
| 87 |
+
mkdir -p "${out_dir}"
|
| 88 |
+
CUDA_VISIBLE_DEVICES="${EVAL_CUDA_VISIBLE_DEVICES:-0}" python scripts/eval_train8_decode_acc.py \
|
| 89 |
+
--runs_glob "runs/${run_name}" \
|
| 90 |
+
--data_dir "${cache}" \
|
| 91 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 92 |
+
--out_dir "${out_dir}" \
|
| 93 |
+
--max_len "${MAX_LEN}" \
|
| 94 |
+
--n_samples "${N_SAMPLES}" \
|
| 95 |
+
--batch_size "${N_SAMPLES}" \
|
| 96 |
+
--latest_only \
|
| 97 |
+
--endpoint_softenings none \
|
| 98 |
+
--steps "${INFER_STEPS}" \
|
| 99 |
+
--decode_rule "${decode_rule}" \
|
| 100 |
+
--time_schedule logit_normal \
|
| 101 |
+
--time_logit_mean -1.5 \
|
| 102 |
+
--time_logit_std 0.8 \
|
| 103 |
+
--model_t_mode post \
|
| 104 |
+
--c_min 1 \
|
| 105 |
+
--c_max "${EVAL_C_MAX}" \
|
| 106 |
+
--early_temp "${EVAL_EARLY_TEMP}" \
|
| 107 |
+
--late_temp "${EVAL_LATE_TEMP}" \
|
| 108 |
+
--final_from state \
|
| 109 |
+
--final_decode argmax
|
| 110 |
+
python - "$out_dir" "$N_SAMPLES" "$GLOBAL_BATCH_SIZE" "$MAX_LEN" "$CURVE_CSV" "$config" "$run_name" "$decode_rule" <<'PY'
|
| 111 |
+
import json
|
| 112 |
+
import sys
|
| 113 |
+
from pathlib import Path
|
| 114 |
+
out = Path(sys.argv[1])
|
| 115 |
+
n = int(sys.argv[2])
|
| 116 |
+
global_batch = int(sys.argv[3])
|
| 117 |
+
max_len = int(sys.argv[4])
|
| 118 |
+
curve = Path(sys.argv[5])
|
| 119 |
+
config = sys.argv[6]
|
| 120 |
+
run_name = sys.argv[7]
|
| 121 |
+
decode_rule = sys.argv[8]
|
| 122 |
+
row = json.loads((out / "decode_token_acc.jsonl").read_text().splitlines()[-1])
|
| 123 |
+
views = int(row["ckpt_step"]) * global_batch
|
| 124 |
+
tokens = views * max_len
|
| 125 |
+
print(
|
| 126 |
+
"RESULT "
|
| 127 |
+
f"config={config} decode={decode_rule} run={run_name} ckpt_step={row['ckpt_step']} "
|
| 128 |
+
f"views={views} token_acc={row['token_acc_mean']:.4f} "
|
| 129 |
+
f"exact={row['exact_count']}/{n} exact_refs={row['exact_ref_count']} "
|
| 130 |
+
f"hits={row['exact_ref_hits']}",
|
| 131 |
+
flush=True,
|
| 132 |
+
)
|
| 133 |
+
with curve.open("a", encoding="utf-8") as f:
|
| 134 |
+
f.write(
|
| 135 |
+
f"{config},{decode_rule},{run_name},{row['ckpt_step']},{views},{tokens},{row['token_acc_mean']},"
|
| 136 |
+
f"{row['exact_count']},{row['exact_ref_count']},\"{row['exact_ref_hits']}\"\n"
|
| 137 |
+
)
|
| 138 |
+
PY
|
| 139 |
+
done
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
run_config() {
|
| 143 |
+
local config="$1"
|
| 144 |
+
local rollout_prob="$2"
|
| 145 |
+
local time_mode="$3"
|
| 146 |
+
local rollout_steps="$4"
|
| 147 |
+
local s_dist="$5"
|
| 148 |
+
local s_min_frac="$6"
|
| 149 |
+
local s_max_frac="$7"
|
| 150 |
+
local s_beta_alpha="$8"
|
| 151 |
+
local s_beta_beta="$9"
|
| 152 |
+
local output_wd="${10}"
|
| 153 |
+
local sync_t="${11}"
|
| 154 |
+
local rollout_steps_min="${12:-${ROLLOUT_TRAIN_STEPS_MIN:--1}}"
|
| 155 |
+
local run_name="${RUN_PREFIX:-train8_ctx1024}_${config}_${GROUP_STAMP}"
|
| 156 |
+
echo "[ctx1024-sampleds] config=${config} run=${run_name} p=${rollout_prob} mode=${time_mode} steps=${rollout_steps} steps_min=${rollout_steps_min} s_dist=${s_dist} s_frac=${s_min_frac}->${s_max_frac} beta=${s_beta_alpha},${s_beta_beta} outwd=${output_wd} sync_t=${sync_t}" | tee -a "${DRIVER_LOG}"
|
| 157 |
+
while :; do
|
| 158 |
+
local step_now
|
| 159 |
+
step_now="$(latest_step "${run_name}")"
|
| 160 |
+
if [[ "${step_now}" -ge "${MAX_TOTAL_STEPS}" ]]; then
|
| 161 |
+
echo "[ctx1024-sampleds] capped config=${config} step=${step_now}" | tee -a "${DRIVER_LOG}"
|
| 162 |
+
break
|
| 163 |
+
fi
|
| 164 |
+
local target_step=$((step_now + STEP_CHUNK))
|
| 165 |
+
if [[ "${target_step}" -gt "${MAX_TOTAL_STEPS}" ]]; then
|
| 166 |
+
target_step="${MAX_TOTAL_STEPS}"
|
| 167 |
+
fi
|
| 168 |
+
local resume_path=""
|
| 169 |
+
if [[ -f "runs/${run_name}/latest.pt" ]]; then
|
| 170 |
+
resume_path="runs/${run_name}/latest.pt"
|
| 171 |
+
fi
|
| 172 |
+
echo "[ctx1024-sampleds] train config=${config} from=${step_now} to=${target_step}" | tee -a "${DRIVER_LOG}"
|
| 173 |
+
CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0,1,2,3}" \
|
| 174 |
+
NPROC_PER_NODE="${NPROC_PER_NODE:-4}" \
|
| 175 |
+
MASTER_PORT="$(free_port)" \
|
| 176 |
+
OWT_CHUNK_CACHE_DIR="${cache}" \
|
| 177 |
+
OWT_EXACT_REPEAT_PER_CHUNK="${OWT_EXACT_REPEAT_PER_CHUNK:-64}" \
|
| 178 |
+
MAX_LEN="${MAX_LEN}" \
|
| 179 |
+
VOCAB_SIZE_OVERRIDE="${vocab_size}" \
|
| 180 |
+
D_MODEL="${D_MODEL:-192}" \
|
| 181 |
+
COND_DIM="${COND_DIM:-64}" \
|
| 182 |
+
N_LAYERS="${N_LAYERS:-3}" \
|
| 183 |
+
N_HEADS="${N_HEADS:-3}" \
|
| 184 |
+
DIM_FF="${DIM_FF:-768}" \
|
| 185 |
+
TOTAL_STEPS="${target_step}" \
|
| 186 |
+
PER_GPU_BATCH_SIZE="${PER_GPU_BATCH_SIZE}" \
|
| 187 |
+
GLOBAL_BATCH_SIZE="${GLOBAL_BATCH_SIZE}" \
|
| 188 |
+
NUM_WORKERS="${NUM_WORKERS:-0}" \
|
| 189 |
+
LOG_EVERY="${LOG_EVERY:-100}" \
|
| 190 |
+
SAVE_EVERY="${STEP_CHUNK}" \
|
| 191 |
+
LATEST_EVERY="${STEP_CHUNK}" \
|
| 192 |
+
WARMUP_STEPS="${WARMUP_STEPS:-10}" \
|
| 193 |
+
LEARNING_RATE="${LEARNING_RATE}" \
|
| 194 |
+
WEIGHT_DECAY="${WEIGHT_DECAY}" \
|
| 195 |
+
OUTPUT_WEIGHT_DECAY="${output_wd}" \
|
| 196 |
+
MUON_IMPL="${MUON_IMPL:-legacy}" \
|
| 197 |
+
MIN_MASK_RATIO=1.0 \
|
| 198 |
+
MAX_MASK_RATIO=1.0 \
|
| 199 |
+
MASK_MIXTURE_LOWK_PROB=0.0 \
|
| 200 |
+
MASK_MIXTURE_ALL_PROB=1.0 \
|
| 201 |
+
LOWK_CLEAN_TOKENS=0 \
|
| 202 |
+
CLEAN_STATE_MODE=onehot \
|
| 203 |
+
TARGET_LOSS=hard_ce \
|
| 204 |
+
DIRICHLET_CONCENTRATION_MIN=1.0 \
|
| 205 |
+
DIRICHLET_CONCENTRATION_MAX=1024 \
|
| 206 |
+
SIMPLEX_BRIDGE_SAMPLER=dirichlet \
|
| 207 |
+
CATEGORICAL_WRONG_PROB_FLOOR=0.0 \
|
| 208 |
+
ROLLOUT_TRAIN_PROB="${rollout_prob}" \
|
| 209 |
+
ROLLOUT_TRAIN_STEPS="${rollout_steps}" \
|
| 210 |
+
ROLLOUT_TRAIN_STEPS_MIN="${rollout_steps_min}" \
|
| 211 |
+
ROLLOUT_TRAIN_INFER_STEPS=1 \
|
| 212 |
+
ROLLOUT_TRAIN_TIME_MODE="${time_mode}" \
|
| 213 |
+
ROLLOUT_TRAIN_S_DIST="${s_dist}" \
|
| 214 |
+
ROLLOUT_TRAIN_S_MIN_FRAC="${s_min_frac}" \
|
| 215 |
+
ROLLOUT_TRAIN_S_MAX_FRAC="${s_max_frac}" \
|
| 216 |
+
ROLLOUT_TRAIN_S_BETA_ALPHA="${s_beta_alpha}" \
|
| 217 |
+
ROLLOUT_TRAIN_S_BETA_BETA="${s_beta_beta}" \
|
| 218 |
+
ROLLOUT_TRAIN_TEMP=1.0 \
|
| 219 |
+
ROLLOUT_TRAIN_MAX_GAMMA=1.0 \
|
| 220 |
+
ROLLOUT_TRAIN_CORRUPT_ONLY=1 \
|
| 221 |
+
ROLLOUT_TRAIN_SAMPLEWISE=1 \
|
| 222 |
+
ROLLOUT_TRAIN_SELECTED_ONLY=1 \
|
| 223 |
+
ROLLOUT_TRAIN_COMPUTE_ALWAYS=0 \
|
| 224 |
+
ROLLOUT_TRAIN_SYNC_T="${sync_t}" \
|
| 225 |
+
T_SAMPLING_MODE="${T_SAMPLING_MODE:-uniform}" \
|
| 226 |
+
RUN_NAME="${run_name}" \
|
| 227 |
+
RESUME_PATH="${resume_path}" \
|
| 228 |
+
bash scripts/launch_lta_owt_gpt2_softendpoint_mn_pilot_4gpu.sh
|
| 229 |
+
echo "[ctx1024-sampleds] eval config=${config} step=${target_step}" | tee -a "${DRIVER_LOG}"
|
| 230 |
+
eval_latest "${config}" "${run_name}" "${target_step}" | tee -a "${DRIVER_LOG}"
|
| 231 |
+
local eval_rule_count
|
| 232 |
+
eval_rule_count="$(python - "$EVAL_DECODE_RULES" <<'PY'
|
| 233 |
+
import sys
|
| 234 |
+
print(len([x for x in sys.argv[1].split(",") if x.strip()]) or 1)
|
| 235 |
+
PY
|
| 236 |
+
)"
|
| 237 |
+
if python - "$CURVE_CSV" "$N_SAMPLES" "$eval_rule_count" <<'PY'
|
| 238 |
+
import csv
|
| 239 |
+
import sys
|
| 240 |
+
from pathlib import Path
|
| 241 |
+
path = Path(sys.argv[1])
|
| 242 |
+
target = min(60, int(sys.argv[2]))
|
| 243 |
+
rule_count = max(1, int(sys.argv[3]))
|
| 244 |
+
rows = list(csv.DictReader(path.open()))
|
| 245 |
+
recent = rows[-rule_count:]
|
| 246 |
+
raise SystemExit(0 if any(int(float(r["exact_count"])) >= target for r in recent) else 1)
|
| 247 |
+
PY
|
| 248 |
+
then
|
| 249 |
+
echo "[ctx1024-sampleds] early-hit config=${config}" | tee -a "${DRIVER_LOG}"
|
| 250 |
+
break
|
| 251 |
+
fi
|
| 252 |
+
done
|
| 253 |
+
}
|
| 254 |
+
|
| 255 |
+
if [[ -n "${WAIT_FOR_RUN}" ]]; then
|
| 256 |
+
echo "[ctx1024-sampleds] waiting for run=${WAIT_FOR_RUN}" | tee -a "${DRIVER_LOG}"
|
| 257 |
+
while pgrep -f "${WAIT_FOR_RUN}" >/dev/null; do
|
| 258 |
+
sleep 60
|
| 259 |
+
done
|
| 260 |
+
fi
|
| 261 |
+
|
| 262 |
+
echo "[ctx1024-sampleds] start stamp=${GROUP_STAMP} len=${MAX_LEN} vocab=${vocab_size} out=${OUT_ROOT}" | tee -a "${DRIVER_LOG}"
|
| 263 |
+
|
| 264 |
+
CONFIGS=(
|
| 265 |
+
"p50_unif0_0p125_outwdm1|0.50|sampled_s|1|uniform|0.0|0.125|2.0|6.0|-1|1"
|
| 266 |
+
"p25_unif0_0p125_outwdm1|0.25|sampled_s|1|uniform|0.0|0.125|2.0|6.0|-1|1"
|
| 267 |
+
"p50_unif0_0p25_outwdm1|0.50|sampled_s|1|uniform|0.0|0.25|2.0|6.0|-1|1"
|
| 268 |
+
"p50_beta2_6_0_0p5_outwdm1|0.50|sampled_s|1|beta|0.0|0.5|2.0|6.0|-1|1"
|
| 269 |
+
"p50_beta2_2_0_0p5_outwdm1|0.50|sampled_s|1|beta|0.0|0.5|2.0|2.0|-1|1"
|
| 270 |
+
"p50_unif0_0p125_outwd0p3|0.50|sampled_s|1|uniform|0.0|0.125|2.0|6.0|0.3|1"
|
| 271 |
+
)
|
| 272 |
+
|
| 273 |
+
if [[ -n "${SWEEP_CONFIGS:-}" ]]; then
|
| 274 |
+
IFS=$'\n' read -r -d '' -a CONFIGS < <(printf '%s\0' "${SWEEP_CONFIGS}") || true
|
| 275 |
+
fi
|
| 276 |
+
|
| 277 |
+
for entry in "${CONFIGS[@]}"; do
|
| 278 |
+
IFS='|' read -r config rollout_prob time_mode rollout_steps s_dist s_min_frac s_max_frac s_beta_alpha s_beta_beta output_wd sync_t rollout_steps_min <<<"${entry}"
|
| 279 |
+
run_config "${config}" "${rollout_prob}" "${time_mode}" "${rollout_steps}" "${s_dist}" "${s_min_frac}" "${s_max_frac}" "${s_beta_alpha}" "${s_beta_beta}" "${output_wd}" "${sync_t}" "${rollout_steps_min:-}"
|
| 280 |
+
done
|
| 281 |
+
|
| 282 |
+
echo "[ctx1024-sampleds] done" | tee -a "${DRIVER_LOG}"
|
LTA_openwebtext_dualt/scripts/run_train8_decode_algo_sweep_len256_latest.sh
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
cd /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt
|
| 5 |
+
|
| 6 |
+
export PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}"
|
| 7 |
+
export TOKENIZERS_PARALLELISM=false
|
| 8 |
+
export PYTHONUNBUFFERED=1
|
| 9 |
+
|
| 10 |
+
DATA_DIR="${DATA_DIR:-/e2e-data/evad-tech-vla/wanghan58/data/small_benchmarks/langflow_2604_11748/openwebtext_lta_cached_chunks/gpt2_len256_train8_compact_overfit}"
|
| 11 |
+
TOKENIZER_PATH="${TOKENIZER_PATH:-/e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-standard/tokenizer.json}"
|
| 12 |
+
MAX_LEN="${MAX_LEN:-256}"
|
| 13 |
+
N_SAMPLES="${N_SAMPLES:-64}"
|
| 14 |
+
INFER_STEPS="${INFER_STEPS:-128}"
|
| 15 |
+
OUT_ROOT="${OUT_ROOT:-docs/lta_samples/metrics_20260517/train8_decode_algo_sweep_len256_latest}"
|
| 16 |
+
LOG_FILE="${LOG_FILE:-logs/train8_decode_algo_sweep_len256_latest/sweep.log}"
|
| 17 |
+
mkdir -p "$(dirname "${LOG_FILE}")" "${OUT_ROOT}"
|
| 18 |
+
|
| 19 |
+
modes=("${MODES:-onehot allcorrupt}")
|
| 20 |
+
variants=(
|
| 21 |
+
"flowmap|state|logit_normal|post|none|ode_trainlogit_post_state"
|
| 22 |
+
"flowmap|endpoint|logit_normal|post|none|ode_trainlogit_post_endpoint"
|
| 23 |
+
"flowmap|blend|logit_normal|post|none|ode_trainlogit_post_blend"
|
| 24 |
+
"flowmap|state|logit_normal|pre|none|ode_trainlogit_pre_state"
|
| 25 |
+
"flowmap|state|uniform|post|none|ode_uniform_post_state"
|
| 26 |
+
"flowmap|state|power_high|post|none|ode_powerhigh_post_state"
|
| 27 |
+
"log_geodesic|state|uniform|post|none|loggeo_uniform_post_state"
|
| 28 |
+
"log_geodesic|state|logit_normal|post|none|loggeo_trainlogit_post_state"
|
| 29 |
+
"flowmap|state|logit_normal|post|uniform|ode_trainlogit_post_state_softuniform"
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
for mode in ${modes[*]}; do
|
| 33 |
+
run_name="${RUN_PREFIX:-train8_n256_compactv969_3l_bs512_hard_ce_}${mode}"
|
| 34 |
+
if [[ ! -d "runs/${run_name}" ]]; then
|
| 35 |
+
echo "[decode-sweep] skip missing run=${run_name}" | tee -a "${LOG_FILE}"
|
| 36 |
+
continue
|
| 37 |
+
fi
|
| 38 |
+
for variant in "${variants[@]}"; do
|
| 39 |
+
IFS='|' read -r decode_rule final_from time_schedule model_t endpoint_softening tag <<<"${variant}"
|
| 40 |
+
out_dir="${OUT_ROOT}/${mode}/${tag}"
|
| 41 |
+
echo "[decode-sweep] $(date) mode=${mode} run=${run_name} tag=${tag}" | tee -a "${LOG_FILE}"
|
| 42 |
+
CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0}" python scripts/eval_train8_decode_acc.py \
|
| 43 |
+
--runs_glob "runs/${run_name}" \
|
| 44 |
+
--data_dir "${DATA_DIR}" \
|
| 45 |
+
--tokenizer_path "${TOKENIZER_PATH}" \
|
| 46 |
+
--out_dir "${out_dir}" \
|
| 47 |
+
--max_len "${MAX_LEN}" \
|
| 48 |
+
--n_samples "${N_SAMPLES}" \
|
| 49 |
+
--batch_size "${N_SAMPLES}" \
|
| 50 |
+
--latest_only \
|
| 51 |
+
--endpoint_softenings "${endpoint_softening}" \
|
| 52 |
+
--steps "${INFER_STEPS}" \
|
| 53 |
+
--decode_rule "${decode_rule}" \
|
| 54 |
+
--time_schedule "${time_schedule}" \
|
| 55 |
+
--time_logit_mean -1.5 \
|
| 56 |
+
--time_logit_std 0.8 \
|
| 57 |
+
--model_t_mode "${model_t}" \
|
| 58 |
+
--c_min 1 \
|
| 59 |
+
--c_max 512 \
|
| 60 |
+
--late_temp 1.0 \
|
| 61 |
+
--final_from "${final_from}" \
|
| 62 |
+
--final_decode argmax \
|
| 63 |
+
2>&1 | tee -a "${LOG_FILE}"
|
| 64 |
+
done
|
| 65 |
+
done
|
| 66 |
+
|
| 67 |
+
python - "$OUT_ROOT" <<'PY' | tee -a "$LOG_FILE"
|
| 68 |
+
import json
|
| 69 |
+
import sys
|
| 70 |
+
from pathlib import Path
|
| 71 |
+
|
| 72 |
+
root = Path(sys.argv[1])
|
| 73 |
+
rows = []
|
| 74 |
+
for path in root.glob("*/*/decode_token_acc.jsonl"):
|
| 75 |
+
for line in path.read_text().splitlines():
|
| 76 |
+
if not line.strip():
|
| 77 |
+
continue
|
| 78 |
+
row = json.loads(line)
|
| 79 |
+
row["mode"] = path.parents[1].name
|
| 80 |
+
row["variant"] = path.parent.name
|
| 81 |
+
rows.append(row)
|
| 82 |
+
rows.sort(key=lambda r: (r["mode"], -float(r.get("token_acc_mean", 0.0)), r["variant"]))
|
| 83 |
+
out = root / "decode_algo_summary.tsv"
|
| 84 |
+
with out.open("w", encoding="utf-8") as f:
|
| 85 |
+
f.write("mode\tvariant\tckpt_step\ttoken_acc_mean\texact_count\texact_ref_count\tdecode_rule\tfinal_from\ttime_schedule\tmodel_t_mode\tendpoint_softening\n")
|
| 86 |
+
for r in rows:
|
| 87 |
+
f.write(
|
| 88 |
+
"\t".join(
|
| 89 |
+
[
|
| 90 |
+
str(r.get("mode")),
|
| 91 |
+
str(r.get("variant")),
|
| 92 |
+
str(r.get("ckpt_step")),
|
| 93 |
+
f"{float(r.get('token_acc_mean', 0.0)):.6f}",
|
| 94 |
+
str(r.get("exact_count")),
|
| 95 |
+
str(r.get("exact_ref_count")),
|
| 96 |
+
str(r.get("decode_rule")),
|
| 97 |
+
str(r.get("final_from")),
|
| 98 |
+
str(r.get("time_schedule")),
|
| 99 |
+
str(r.get("model_t_mode")),
|
| 100 |
+
str(r.get("endpoint_softening")),
|
| 101 |
+
]
|
| 102 |
+
)
|
| 103 |
+
+ "\n"
|
| 104 |
+
)
|
| 105 |
+
print(out)
|
| 106 |
+
for r in rows[:10]:
|
| 107 |
+
print(
|
| 108 |
+
"SWEEP_RESULT "
|
| 109 |
+
f"mode={r.get('mode')} variant={r.get('variant')} step={r.get('ckpt_step')} "
|
| 110 |
+
f"token_acc={float(r.get('token_acc_mean', 0.0)):.4f} "
|
| 111 |
+
f"exact={r.get('exact_count')}/{r.get('n_gen')} refs={r.get('exact_ref_count')}"
|
| 112 |
+
)
|
| 113 |
+
PY
|
LTA_openwebtext_dualt/scripts/sweep_categorical_c1024_late_refresh_20260506.py
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
import argparse
|
| 5 |
+
import importlib.util
|
| 6 |
+
import json
|
| 7 |
+
import math
|
| 8 |
+
import sys
|
| 9 |
+
from dataclasses import asdict, dataclass
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
|
| 12 |
+
import torch
|
| 13 |
+
import torch.nn.functional as F
|
| 14 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
BASE_PATH = Path(__file__).with_name("eval_lm1b_200k_methods_genppl_20260506.py")
|
| 18 |
+
spec = importlib.util.spec_from_file_location("eval_lm1b_200k_methods_genppl_20260506", BASE_PATH)
|
| 19 |
+
if spec is None or spec.loader is None:
|
| 20 |
+
raise RuntimeError(f"Could not load {BASE_PATH}")
|
| 21 |
+
base = importlib.util.module_from_spec(spec)
|
| 22 |
+
sys.modules[spec.name] = base
|
| 23 |
+
spec.loader.exec_module(base)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
@dataclass(frozen=True)
|
| 27 |
+
class RefreshCfg:
|
| 28 |
+
label: str
|
| 29 |
+
refresh_frac: float
|
| 30 |
+
sample_temp: float = 0.8
|
| 31 |
+
top_k: int = 16
|
| 32 |
+
select: str = "low_conf"
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def default_configs() -> list[RefreshCfg]:
|
| 36 |
+
return [
|
| 37 |
+
RefreshCfg("base_argmax", 0.0, top_k=1),
|
| 38 |
+
RefreshCfg("lowconf05_t0p8_top16", 0.05, 0.8, 16),
|
| 39 |
+
RefreshCfg("lowconf10_t0p8_top16", 0.10, 0.8, 16),
|
| 40 |
+
RefreshCfg("lowconf15_t0p8_top16", 0.15, 0.8, 16),
|
| 41 |
+
RefreshCfg("lowconf20_t0p8_top16", 0.20, 0.8, 16),
|
| 42 |
+
RefreshCfg("lowconf10_t1p0_top32", 0.10, 1.0, 32),
|
| 43 |
+
RefreshCfg("lowconf15_t1p0_top32", 0.15, 1.0, 32),
|
| 44 |
+
RefreshCfg("lowconf20_t1p0_top64", 0.20, 1.0, 64),
|
| 45 |
+
RefreshCfg("random10_t0p8_top16", 0.10, 0.8, 16, select="random"),
|
| 46 |
+
RefreshCfg("random15_t0p8_top16", 0.15, 0.8, 16, select="random"),
|
| 47 |
+
]
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def load_endpoint_model(checkpoint: str, tokenizer, device: torch.device):
|
| 51 |
+
ckpt = torch.load(checkpoint, map_location="cpu", weights_only=False)
|
| 52 |
+
model = base.build_endpoint_model(ckpt, tokenizer, "categorical_fullvocab", device)
|
| 53 |
+
return ckpt, model
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def sample_from_probs(probs: torch.Tensor, *, temp: float, top_k: int) -> torch.Tensor:
|
| 57 |
+
if top_k <= 1:
|
| 58 |
+
return probs.argmax(dim=-1)
|
| 59 |
+
k = min(int(top_k), probs.size(-1))
|
| 60 |
+
vals, inds = torch.topk(probs, k=k, dim=-1)
|
| 61 |
+
vals = vals.clamp_min(1e-20)
|
| 62 |
+
if temp != 1.0:
|
| 63 |
+
vals = vals.pow(1.0 / float(temp))
|
| 64 |
+
vals = vals / vals.sum(dim=-1, keepdim=True).clamp_min(1e-20)
|
| 65 |
+
picked = torch.multinomial(vals.reshape(-1, k), num_samples=1).view(*probs.shape[:-1])
|
| 66 |
+
return inds.gather(-1, picked.unsqueeze(-1)).squeeze(-1)
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def apply_refresh(final_probs: torch.Tensor, cfg: RefreshCfg) -> torch.Tensor:
|
| 70 |
+
ids = final_probs.argmax(dim=-1)
|
| 71 |
+
if cfg.refresh_frac <= 0:
|
| 72 |
+
return ids
|
| 73 |
+
bs, length, _ = final_probs.shape
|
| 74 |
+
n_refresh = max(1, int(math.ceil(float(cfg.refresh_frac) * length)))
|
| 75 |
+
conf = final_probs.max(dim=-1).values
|
| 76 |
+
if cfg.select == "low_conf":
|
| 77 |
+
order_score = -conf
|
| 78 |
+
elif cfg.select == "random":
|
| 79 |
+
order_score = torch.rand_like(conf)
|
| 80 |
+
else:
|
| 81 |
+
raise ValueError(f"unknown select={cfg.select!r}")
|
| 82 |
+
chosen = torch.topk(order_score, k=min(n_refresh, length), dim=-1).indices
|
| 83 |
+
sampled = sample_from_probs(final_probs, temp=cfg.sample_temp, top_k=cfg.top_k)
|
| 84 |
+
return ids.scatter(1, chosen, sampled.gather(1, chosen))
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
@torch.inference_mode()
|
| 88 |
+
def generate_variants(
|
| 89 |
+
model,
|
| 90 |
+
tokenizer,
|
| 91 |
+
configs: list[RefreshCfg],
|
| 92 |
+
*,
|
| 93 |
+
n_samples: int,
|
| 94 |
+
batch_size: int,
|
| 95 |
+
max_len: int,
|
| 96 |
+
steps: int,
|
| 97 |
+
seed: int,
|
| 98 |
+
device: torch.device,
|
| 99 |
+
) -> tuple[dict[str, list[list[int]]], dict[str, list[str]], dict]:
|
| 100 |
+
torch.manual_seed(seed)
|
| 101 |
+
eps = 1e-8
|
| 102 |
+
concentration_min = 1.0
|
| 103 |
+
concentration_max = 1024.0
|
| 104 |
+
all_ids = {cfg.label: [] for cfg in configs}
|
| 105 |
+
all_texts = {cfg.label: [] for cfg in configs}
|
| 106 |
+
remaining = n_samples
|
| 107 |
+
while remaining > 0:
|
| 108 |
+
bs = min(batch_size, remaining)
|
| 109 |
+
probs = base.sample_noise_simplex(
|
| 110 |
+
(bs, max_len),
|
| 111 |
+
tokenizer.vocab_size,
|
| 112 |
+
device,
|
| 113 |
+
eps,
|
| 114 |
+
noise_mode="dirichlet",
|
| 115 |
+
target_prob=1.0,
|
| 116 |
+
noise_sigma=-1.0,
|
| 117 |
+
dirichlet_concentration=1.0,
|
| 118 |
+
)
|
| 119 |
+
attn = torch.ones((bs, max_len), dtype=torch.bool, device=device)
|
| 120 |
+
last_endpoint = probs
|
| 121 |
+
for step in range(steps):
|
| 122 |
+
model_t = torch.full((bs,), 0.5, dtype=torch.float32, device=device)
|
| 123 |
+
logits = model(base.state_for_model(model, probs, eps), model_t, attn).float() / 1.3
|
| 124 |
+
endpoint = F.softmax(logits, dim=-1)
|
| 125 |
+
last_endpoint = endpoint
|
| 126 |
+
|
| 127 |
+
support_t = (step + 1) / max(steps, 1)
|
| 128 |
+
semantic_t = support_t**1.5
|
| 129 |
+
anchor = probs.clamp_min(eps)
|
| 130 |
+
anchor = anchor / anchor.sum(dim=-1, keepdim=True).clamp_min(eps)
|
| 131 |
+
guided = (1.0 - semantic_t) * anchor + semantic_t * endpoint
|
| 132 |
+
guided = guided.clamp_min(eps)
|
| 133 |
+
guided = guided / guided.sum(dim=-1, keepdim=True).clamp_min(eps)
|
| 134 |
+
|
| 135 |
+
mean = (1.0 - support_t) / float(tokenizer.vocab_size) + support_t * guided
|
| 136 |
+
mean = mean.clamp_min(eps)
|
| 137 |
+
mean = mean / mean.sum(dim=-1, keepdim=True).clamp_min(eps)
|
| 138 |
+
conc = math.exp(
|
| 139 |
+
math.log(concentration_min)
|
| 140 |
+
+ support_t * (math.log(concentration_max) - math.log(concentration_min))
|
| 141 |
+
)
|
| 142 |
+
alpha = (mean * conc).clamp_min(eps)
|
| 143 |
+
probs = torch._standard_gamma(alpha).clamp_min(eps)
|
| 144 |
+
probs = probs / probs.sum(dim=-1, keepdim=True).clamp_min(eps)
|
| 145 |
+
|
| 146 |
+
final_probs = 0.5 * probs + 0.5 * last_endpoint
|
| 147 |
+
final_probs = final_probs.clamp_min(eps)
|
| 148 |
+
final_probs = final_probs / final_probs.sum(dim=-1, keepdim=True).clamp_min(eps)
|
| 149 |
+
for cfg in configs:
|
| 150 |
+
ids = apply_refresh(final_probs, cfg).detach().cpu().tolist()
|
| 151 |
+
all_ids[cfg.label].extend(ids)
|
| 152 |
+
all_texts[cfg.label].extend(tokenizer.decode(row, stop_at_eos=False, skip_special_tokens=False) for row in ids)
|
| 153 |
+
remaining -= bs
|
| 154 |
+
print(f"[decode] generated base states {n_samples - remaining}/{n_samples}", flush=True)
|
| 155 |
+
|
| 156 |
+
base_decode = {
|
| 157 |
+
"kind": "categorical_fullvocab",
|
| 158 |
+
"steps": steps,
|
| 159 |
+
"model_t_mode": "const05",
|
| 160 |
+
"base_decode_rule": "dual_line_resample_rolling",
|
| 161 |
+
"support_power": 1.0,
|
| 162 |
+
"semantic_power": 1.5,
|
| 163 |
+
"endpoint_temp": 1.3,
|
| 164 |
+
"final_from": "blend_then_refresh",
|
| 165 |
+
"n_samples": n_samples,
|
| 166 |
+
"seed": seed,
|
| 167 |
+
}
|
| 168 |
+
return all_ids, all_texts, base_decode
|
| 169 |
+
|
| 170 |
+
|
| 171 |
+
def main() -> None:
|
| 172 |
+
p = argparse.ArgumentParser()
|
| 173 |
+
p.add_argument(
|
| 174 |
+
"--checkpoint",
|
| 175 |
+
default="runs/lta_lm1b_dirichlet_categorical_fullvocab_dualt_flmpack_onehot_hardce_ddit_small_len128_gbs512_8gpu_1m_nw0/latest.pt",
|
| 176 |
+
)
|
| 177 |
+
p.add_argument("--tokenizer_path", required=True)
|
| 178 |
+
p.add_argument("--scorer", required=True)
|
| 179 |
+
p.add_argument("--out_dir", required=True)
|
| 180 |
+
p.add_argument("--n_samples", type=int, default=128)
|
| 181 |
+
p.add_argument("--max_len", type=int, default=128)
|
| 182 |
+
p.add_argument("--steps", type=int, default=1024)
|
| 183 |
+
p.add_argument("--decode_batch", type=int, default=16)
|
| 184 |
+
p.add_argument("--score_batch", type=int, default=8)
|
| 185 |
+
p.add_argument("--score_max_length", type=int, default=256)
|
| 186 |
+
p.add_argument("--seed", type=int, default=20260506)
|
| 187 |
+
p.add_argument("--only", default="", help="Optional comma-separated config labels.")
|
| 188 |
+
args = p.parse_args()
|
| 189 |
+
|
| 190 |
+
selected = {x.strip() for x in args.only.split(",") if x.strip()}
|
| 191 |
+
configs = [c for c in default_configs() if not selected or c.label in selected]
|
| 192 |
+
if not configs:
|
| 193 |
+
raise SystemExit(f"No configs selected by --only={args.only!r}")
|
| 194 |
+
|
| 195 |
+
out_dir = Path(args.out_dir)
|
| 196 |
+
out_dir.mkdir(parents=True, exist_ok=True)
|
| 197 |
+
summary_path = out_dir / "summary.jsonl"
|
| 198 |
+
summary_path.write_text("", encoding="utf-8")
|
| 199 |
+
|
| 200 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 201 |
+
tokenizer = base.BpeTextTokenizer.from_file(args.tokenizer_path)
|
| 202 |
+
ckpt, model = load_endpoint_model(args.checkpoint, tokenizer, device)
|
| 203 |
+
step = ckpt.get("step")
|
| 204 |
+
print(f"[load] checkpoint={args.checkpoint} step={step}", flush=True)
|
| 205 |
+
|
| 206 |
+
scorer_tok = AutoTokenizer.from_pretrained(args.scorer)
|
| 207 |
+
if scorer_tok.pad_token_id is None:
|
| 208 |
+
scorer_tok.pad_token = scorer_tok.eos_token
|
| 209 |
+
scorer_tok.pad_token_id = scorer_tok.eos_token_id
|
| 210 |
+
scorer = AutoModelForCausalLM.from_pretrained(args.scorer).to(device).eval()
|
| 211 |
+
if getattr(scorer.config, "pad_token_id", None) is None:
|
| 212 |
+
scorer.config.pad_token_id = scorer_tok.pad_token_id
|
| 213 |
+
|
| 214 |
+
ids_by_label, texts_by_label, base_decode = generate_variants(
|
| 215 |
+
model,
|
| 216 |
+
tokenizer,
|
| 217 |
+
configs,
|
| 218 |
+
n_samples=args.n_samples,
|
| 219 |
+
batch_size=args.decode_batch,
|
| 220 |
+
max_len=args.max_len,
|
| 221 |
+
steps=args.steps,
|
| 222 |
+
seed=args.seed,
|
| 223 |
+
device=device,
|
| 224 |
+
)
|
| 225 |
+
|
| 226 |
+
summaries = []
|
| 227 |
+
with summary_path.open("a", encoding="utf-8") as sf:
|
| 228 |
+
for cfg in configs:
|
| 229 |
+
decode = dict(base_decode)
|
| 230 |
+
decode.update({"decode_rule": "late_low_conf_refresh", "refresh": asdict(cfg)})
|
| 231 |
+
target = base.EvalTarget(f"categorical_c1024_late_refresh_{cfg.label}", "categorical_fullvocab", args.checkpoint)
|
| 232 |
+
summary = base.score_and_write(
|
| 233 |
+
target=target,
|
| 234 |
+
checkpoint=args.checkpoint,
|
| 235 |
+
step=step,
|
| 236 |
+
decode=decode,
|
| 237 |
+
ids=ids_by_label[cfg.label],
|
| 238 |
+
raw_texts=texts_by_label[cfg.label],
|
| 239 |
+
scorer=scorer,
|
| 240 |
+
scorer_tok=scorer_tok,
|
| 241 |
+
score_batch=args.score_batch,
|
| 242 |
+
score_max_length=args.score_max_length,
|
| 243 |
+
device=device,
|
| 244 |
+
out_dir=out_dir,
|
| 245 |
+
)
|
| 246 |
+
summary["config"] = asdict(cfg)
|
| 247 |
+
sf.write(json.dumps(summary, ensure_ascii=False) + "\n")
|
| 248 |
+
sf.flush()
|
| 249 |
+
summaries.append(summary)
|
| 250 |
+
div = summary["diversity"]
|
| 251 |
+
print(
|
| 252 |
+
f"[summary] {cfg.label} raw={summary['raw_genppl']['ppl']:.3f} "
|
| 253 |
+
f"strip={summary['stripped_genppl']['ppl']:.3f} "
|
| 254 |
+
f"ent={div['sample_entropy']:.3f} d2={div['distinct_2']:.3f} "
|
| 255 |
+
f"top={div['top_token_mass']:.3f}",
|
| 256 |
+
flush=True,
|
| 257 |
+
)
|
| 258 |
+
|
| 259 |
+
table_path = out_dir / "summary.tsv"
|
| 260 |
+
with table_path.open("w", encoding="utf-8") as f:
|
| 261 |
+
f.write(
|
| 262 |
+
"label\traw_genppl\tstripped_genppl\tsample_entropy\tdistinct_2\ttop_token_mass\t"
|
| 263 |
+
"refresh_frac\tsample_temp\ttop_k\tselect\tmeets_target\n"
|
| 264 |
+
)
|
| 265 |
+
for summary in summaries:
|
| 266 |
+
div = summary["diversity"]
|
| 267 |
+
raw = summary["raw_genppl"]["ppl"]
|
| 268 |
+
ent = div["sample_entropy"]
|
| 269 |
+
cfg = summary["config"]
|
| 270 |
+
meets = raw <= 30.0 and ent >= 4.1
|
| 271 |
+
f.write(
|
| 272 |
+
f"{cfg['label']}\t{raw:.6f}\t{summary['stripped_genppl']['ppl']:.6f}\t"
|
| 273 |
+
f"{ent:.6f}\t{div['distinct_2']:.6f}\t{div['top_token_mass']:.6f}\t"
|
| 274 |
+
f"{cfg['refresh_frac']:.3f}\t{cfg['sample_temp']:.3f}\t{cfg['top_k']}\t"
|
| 275 |
+
f"{cfg['select']}\t{int(meets)}\n"
|
| 276 |
+
)
|
| 277 |
+
print(f"[done] {out_dir}", flush=True)
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
if __name__ == "__main__":
|
| 281 |
+
main()
|