Clean Atom2.7m package naming and benchmark entrypoint
Browse files- README.md +3 -3
- benchmark_atom_arithmark.py +290 -0
- benchmark_results/lm_eval/results_2026-07-04T17-16-59.922847.json +355 -0
- tokenization_atom.py +1 -1
- tokenizer_utils.py +44 -24
README.md
CHANGED
|
@@ -90,12 +90,12 @@ with torch.no_grad():
|
|
| 90 |
Use the included benchmark script:
|
| 91 |
|
| 92 |
```bash
|
| 93 |
-
python
|
| 94 |
--checkpoint . \
|
| 95 |
--data-path arithmark_2.0.jsonl \
|
| 96 |
--batch-size 64 \
|
| 97 |
--device cuda \
|
| 98 |
-
--output benchmark_results/
|
| 99 |
```
|
| 100 |
|
| 101 |
### lm-evaluation-harness
|
|
@@ -157,7 +157,7 @@ Synthetic-Arithmetic is canonical integer equation data. The training curriculum
|
|
| 157 |
- `model.safetensors`: model weights
|
| 158 |
- `config.json`, `config.py`, `configuration_gpt.py`, `model.py`: custom model code
|
| 159 |
- `tokenizer.json`, `tokenization_atom.py`: tokenizer files and remote-code wrapper
|
| 160 |
-
- `
|
| 161 |
- `arithmark_2.0.jsonl`: local ArithMark 2.0 data for the standalone benchmark script
|
| 162 |
- `pretraining_curriculum.json`: training curriculum
|
| 163 |
|
|
|
|
| 90 |
Use the included benchmark script:
|
| 91 |
|
| 92 |
```bash
|
| 93 |
+
python benchmark_atom_arithmark.py \
|
| 94 |
--checkpoint . \
|
| 95 |
--data-path arithmark_2.0.jsonl \
|
| 96 |
--batch-size 64 \
|
| 97 |
--device cuda \
|
| 98 |
+
--output benchmark_results/atom_arithmark_2.0_results.json
|
| 99 |
```
|
| 100 |
|
| 101 |
### lm-evaluation-harness
|
|
|
|
| 157 |
- `model.safetensors`: model weights
|
| 158 |
- `config.json`, `config.py`, `configuration_gpt.py`, `model.py`: custom model code
|
| 159 |
- `tokenizer.json`, `tokenization_atom.py`: tokenizer files and remote-code wrapper
|
| 160 |
+
- `benchmark_atom_arithmark.py`: ArithMark evaluation
|
| 161 |
- `arithmark_2.0.jsonl`: local ArithMark 2.0 data for the standalone benchmark script
|
| 162 |
- `pretraining_curriculum.json`: training curriculum
|
| 163 |
|
benchmark_atom_arithmark.py
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Score an Atom GPT checkpoint on ArithMark 2.0."""
|
| 2 |
+
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
import argparse
|
| 6 |
+
from collections import Counter
|
| 7 |
+
from contextlib import nullcontext
|
| 8 |
+
import json
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
import re
|
| 11 |
+
import urllib.request
|
| 12 |
+
|
| 13 |
+
import torch
|
| 14 |
+
import torch.nn.functional as F
|
| 15 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
DATA_URL = (
|
| 19 |
+
"https://huggingface.co/datasets/AxiomicLabs/Arithmark-2.0/"
|
| 20 |
+
"resolve/main/arithmark_2.0.jsonl"
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def ensure_data(path: Path) -> Path:
|
| 25 |
+
if path.exists():
|
| 26 |
+
return path
|
| 27 |
+
path.parent.mkdir(parents=True, exist_ok=True)
|
| 28 |
+
urllib.request.urlretrieve(DATA_URL, path)
|
| 29 |
+
return path
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def load_examples(path: Path, *, max_examples: int = 0) -> list[dict]:
|
| 33 |
+
examples = []
|
| 34 |
+
with path.open("r", encoding="utf-8") as handle:
|
| 35 |
+
for line in handle:
|
| 36 |
+
if not line.strip():
|
| 37 |
+
continue
|
| 38 |
+
examples.append(json.loads(line))
|
| 39 |
+
if max_examples > 0 and len(examples) >= max_examples:
|
| 40 |
+
break
|
| 41 |
+
return examples
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def _encoded_choice(
|
| 45 |
+
tokenizer,
|
| 46 |
+
context: str,
|
| 47 |
+
ending: str,
|
| 48 |
+
) -> tuple[list[int], int]:
|
| 49 |
+
context_ids = tokenizer(context, add_special_tokens=False).input_ids
|
| 50 |
+
full_ids = tokenizer(context + ending, add_special_tokens=False).input_ids
|
| 51 |
+
continuation_length = len(full_ids) - len(context_ids)
|
| 52 |
+
return full_ids, continuation_length
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
@torch.inference_mode()
|
| 56 |
+
def evaluate(
|
| 57 |
+
model,
|
| 58 |
+
tokenizer,
|
| 59 |
+
examples: list[dict],
|
| 60 |
+
*,
|
| 61 |
+
device: torch.device,
|
| 62 |
+
batch_size: int,
|
| 63 |
+
dump_failures: bool = False,
|
| 64 |
+
failure_operator_count: int | None = None,
|
| 65 |
+
max_failures: int = 100,
|
| 66 |
+
) -> dict:
|
| 67 |
+
correct = 0
|
| 68 |
+
total = 0
|
| 69 |
+
by_operator_count: dict[str, list[int]] = {}
|
| 70 |
+
by_topic: dict[str, list[int]] = {}
|
| 71 |
+
failures: list[dict] = []
|
| 72 |
+
failure_summary: Counter[tuple[str, str, str]] = Counter()
|
| 73 |
+
model.eval()
|
| 74 |
+
pad_id = tokenizer.pad_token_id
|
| 75 |
+
if pad_id is None:
|
| 76 |
+
pad_id = tokenizer.eos_token_id if tokenizer.eos_token_id is not None else 0
|
| 77 |
+
|
| 78 |
+
for start in range(0, len(examples), batch_size):
|
| 79 |
+
batch_examples = examples[start : start + batch_size]
|
| 80 |
+
encoded = []
|
| 81 |
+
offsets = []
|
| 82 |
+
for example in batch_examples:
|
| 83 |
+
flat_start = len(encoded)
|
| 84 |
+
encoded.extend(
|
| 85 |
+
_encoded_choice(tokenizer, example["ctx"], ending)
|
| 86 |
+
for ending in example["endings"]
|
| 87 |
+
)
|
| 88 |
+
offsets.append((flat_start, len(example["endings"])))
|
| 89 |
+
|
| 90 |
+
max_length = max(len(item[0]) for item in encoded)
|
| 91 |
+
input_ids = torch.full(
|
| 92 |
+
(len(encoded), max_length),
|
| 93 |
+
int(pad_id),
|
| 94 |
+
dtype=torch.long,
|
| 95 |
+
device=device,
|
| 96 |
+
)
|
| 97 |
+
attention_mask = torch.zeros_like(input_ids, dtype=torch.bool)
|
| 98 |
+
lengths = []
|
| 99 |
+
continuation_lengths = []
|
| 100 |
+
for row, (ids, continuation_length) in enumerate(encoded):
|
| 101 |
+
length = len(ids)
|
| 102 |
+
input_ids[row, :length] = torch.tensor(ids, device=device)
|
| 103 |
+
attention_mask[row, :length] = True
|
| 104 |
+
lengths.append(length)
|
| 105 |
+
continuation_lengths.append(continuation_length)
|
| 106 |
+
|
| 107 |
+
autocast = (
|
| 108 |
+
torch.autocast(device_type="cuda", dtype=torch.bfloat16)
|
| 109 |
+
if device.type == "cuda"
|
| 110 |
+
else nullcontext()
|
| 111 |
+
)
|
| 112 |
+
with autocast:
|
| 113 |
+
logits = model(
|
| 114 |
+
input_ids=input_ids,
|
| 115 |
+
attention_mask=attention_mask,
|
| 116 |
+
).logits
|
| 117 |
+
log_probs = F.log_softmax(logits.float(), dim=-1)
|
| 118 |
+
|
| 119 |
+
for example_index, example in enumerate(batch_examples):
|
| 120 |
+
flat_start, choice_count = offsets[example_index]
|
| 121 |
+
likelihoods = []
|
| 122 |
+
for choice_index in range(choice_count):
|
| 123 |
+
row = flat_start + choice_index
|
| 124 |
+
length = lengths[row]
|
| 125 |
+
continuation_length = continuation_lengths[row]
|
| 126 |
+
continuation_start = length - continuation_length
|
| 127 |
+
likelihood = 0.0
|
| 128 |
+
for position in range(continuation_start, length):
|
| 129 |
+
likelihood += float(
|
| 130 |
+
log_probs[row, position - 1, input_ids[row, position]].item()
|
| 131 |
+
)
|
| 132 |
+
likelihoods.append(likelihood)
|
| 133 |
+
|
| 134 |
+
prediction = max(range(choice_count), key=likelihoods.__getitem__)
|
| 135 |
+
label = int(example["label"])
|
| 136 |
+
matched = prediction == label
|
| 137 |
+
correct += int(matched)
|
| 138 |
+
total += 1
|
| 139 |
+
metadata = example.get("metadata", {})
|
| 140 |
+
operator_count = str(metadata.get("operator_count", "unknown"))
|
| 141 |
+
topic = str(metadata.get("topic", "unknown"))
|
| 142 |
+
for grouped, key in (
|
| 143 |
+
(by_operator_count, operator_count),
|
| 144 |
+
(by_topic, topic),
|
| 145 |
+
):
|
| 146 |
+
group = grouped.setdefault(key, [0, 0])
|
| 147 |
+
group[0] += int(matched)
|
| 148 |
+
group[1] += 1
|
| 149 |
+
|
| 150 |
+
if not matched and dump_failures:
|
| 151 |
+
op_count_int = None
|
| 152 |
+
try:
|
| 153 |
+
op_count_int = int(operator_count)
|
| 154 |
+
except ValueError:
|
| 155 |
+
pass
|
| 156 |
+
if failure_operator_count is None or op_count_int == failure_operator_count:
|
| 157 |
+
context = str(example["ctx"]).strip()
|
| 158 |
+
expression = context[:-1].strip() if context.endswith("=") else context
|
| 159 |
+
operands = [int(value) for value in re.findall(r"\d+", expression)]
|
| 160 |
+
operator = "".join(re.findall(r"[+\-*/]", expression))
|
| 161 |
+
predicted_answer = str(example["endings"][prediction]).strip()
|
| 162 |
+
correct_answer = str(example["endings"][label]).strip()
|
| 163 |
+
width = max((len(str(value)) for value in operands), default=0)
|
| 164 |
+
failure_summary[(topic, operator, f"width={width}")] += 1
|
| 165 |
+
if len(failures) < max_failures:
|
| 166 |
+
failures.append(
|
| 167 |
+
{
|
| 168 |
+
"ctx": context,
|
| 169 |
+
"topic": topic,
|
| 170 |
+
"operator_count": operator_count,
|
| 171 |
+
"operator": operator,
|
| 172 |
+
"operands": operands,
|
| 173 |
+
"max_operand_digits": width,
|
| 174 |
+
"correct_answer": correct_answer,
|
| 175 |
+
"predicted_answer": predicted_answer,
|
| 176 |
+
"choices": [str(value).strip() for value in example["endings"]],
|
| 177 |
+
"choice_scores": [round(value, 4) for value in likelihoods],
|
| 178 |
+
"score_margin_correct_minus_predicted": round(
|
| 179 |
+
likelihoods[label] - likelihoods[prediction],
|
| 180 |
+
4,
|
| 181 |
+
),
|
| 182 |
+
}
|
| 183 |
+
)
|
| 184 |
+
|
| 185 |
+
results = {
|
| 186 |
+
"benchmark": "arithmark_2.0",
|
| 187 |
+
"model_type": "atom_gpt",
|
| 188 |
+
"accuracy": correct / max(total, 1),
|
| 189 |
+
"correct": correct,
|
| 190 |
+
"total": total,
|
| 191 |
+
"by_operator_count": {
|
| 192 |
+
key: {
|
| 193 |
+
"accuracy": values[0] / max(values[1], 1),
|
| 194 |
+
"correct": values[0],
|
| 195 |
+
"total": values[1],
|
| 196 |
+
}
|
| 197 |
+
for key, values in sorted(by_operator_count.items())
|
| 198 |
+
},
|
| 199 |
+
"by_topic": {
|
| 200 |
+
key: {
|
| 201 |
+
"accuracy": values[0] / max(values[1], 1),
|
| 202 |
+
"correct": values[0],
|
| 203 |
+
"total": values[1],
|
| 204 |
+
}
|
| 205 |
+
for key, values in sorted(by_topic.items())
|
| 206 |
+
},
|
| 207 |
+
}
|
| 208 |
+
if dump_failures:
|
| 209 |
+
results["failure_summary"] = {
|
| 210 |
+
"|".join(key): value
|
| 211 |
+
for key, value in failure_summary.most_common()
|
| 212 |
+
}
|
| 213 |
+
results["failures"] = failures
|
| 214 |
+
return results
|
| 215 |
+
|
| 216 |
+
|
| 217 |
+
def parse_args() -> argparse.Namespace:
|
| 218 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 219 |
+
parser.add_argument("--checkpoint", type=Path, default=Path("."))
|
| 220 |
+
parser.add_argument("--data-path", type=Path, default=Path("arithmark_2.0.jsonl"))
|
| 221 |
+
parser.add_argument("--batch-size", type=int, default=64)
|
| 222 |
+
parser.add_argument("--device", default="auto")
|
| 223 |
+
parser.add_argument("--dtype", default="auto", choices=("auto", "float32", "bfloat16", "float16"))
|
| 224 |
+
parser.add_argument("--output", type=Path)
|
| 225 |
+
parser.add_argument(
|
| 226 |
+
"--max-examples",
|
| 227 |
+
type=int,
|
| 228 |
+
default=0,
|
| 229 |
+
help="Evaluate only the first N examples. Default evaluates all examples.",
|
| 230 |
+
)
|
| 231 |
+
parser.add_argument(
|
| 232 |
+
"--dump-failures",
|
| 233 |
+
action="store_true",
|
| 234 |
+
help="Include incorrectly scored examples and grouped failure summary.",
|
| 235 |
+
)
|
| 236 |
+
parser.add_argument(
|
| 237 |
+
"--failure-operator-count",
|
| 238 |
+
type=int,
|
| 239 |
+
default=None,
|
| 240 |
+
help="Only dump failures with this operator count, e.g. 1 for easy examples.",
|
| 241 |
+
)
|
| 242 |
+
parser.add_argument("--max-failures", type=int, default=100)
|
| 243 |
+
return parser.parse_args()
|
| 244 |
+
|
| 245 |
+
|
| 246 |
+
def main() -> None:
|
| 247 |
+
args = parse_args()
|
| 248 |
+
if args.device == "auto":
|
| 249 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 250 |
+
else:
|
| 251 |
+
device = torch.device(args.device)
|
| 252 |
+
|
| 253 |
+
data_path = ensure_data(args.data_path)
|
| 254 |
+
examples = load_examples(data_path, max_examples=args.max_examples)
|
| 255 |
+
dtype = None
|
| 256 |
+
if args.dtype == "float32":
|
| 257 |
+
dtype = torch.float32
|
| 258 |
+
elif args.dtype == "bfloat16":
|
| 259 |
+
dtype = torch.bfloat16
|
| 260 |
+
elif args.dtype == "float16":
|
| 261 |
+
dtype = torch.float16
|
| 262 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 263 |
+
args.checkpoint,
|
| 264 |
+
dtype=dtype,
|
| 265 |
+
trust_remote_code=True,
|
| 266 |
+
).to(device)
|
| 267 |
+
tokenizer = AutoTokenizer.from_pretrained(args.checkpoint, trust_remote_code=True)
|
| 268 |
+
if tokenizer.pad_token_id is None:
|
| 269 |
+
tokenizer.pad_token = tokenizer.eos_token
|
| 270 |
+
results = evaluate(
|
| 271 |
+
model,
|
| 272 |
+
tokenizer,
|
| 273 |
+
examples,
|
| 274 |
+
device=device,
|
| 275 |
+
batch_size=args.batch_size,
|
| 276 |
+
dump_failures=args.dump_failures,
|
| 277 |
+
failure_operator_count=args.failure_operator_count,
|
| 278 |
+
max_failures=args.max_failures,
|
| 279 |
+
)
|
| 280 |
+
print(json.dumps(results, indent=2, sort_keys=True))
|
| 281 |
+
if args.output:
|
| 282 |
+
args.output.parent.mkdir(parents=True, exist_ok=True)
|
| 283 |
+
args.output.write_text(
|
| 284 |
+
json.dumps(results, indent=2, sort_keys=True) + "\n",
|
| 285 |
+
encoding="utf-8",
|
| 286 |
+
)
|
| 287 |
+
|
| 288 |
+
|
| 289 |
+
if __name__ == "__main__":
|
| 290 |
+
main()
|
benchmark_results/lm_eval/results_2026-07-04T17-16-59.922847.json
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"results": {
|
| 3 |
+
"hellaswag": {
|
| 4 |
+
"name": "hellaswag",
|
| 5 |
+
"alias": "hellaswag",
|
| 6 |
+
"sample_len": 10042,
|
| 7 |
+
"acc,none": 0.2669786895040829,
|
| 8 |
+
"acc_stderr,none": 0.004414770331224705,
|
| 9 |
+
"acc_norm,none": 0.2700657239593706,
|
| 10 |
+
"acc_norm_stderr,none": 0.0044308610336166706
|
| 11 |
+
},
|
| 12 |
+
"arc_easy": {
|
| 13 |
+
"name": "arc_easy",
|
| 14 |
+
"alias": "arc_easy",
|
| 15 |
+
"sample_len": 2376,
|
| 16 |
+
"acc,none": 0.32154882154882153,
|
| 17 |
+
"acc_stderr,none": 0.009584091575640627,
|
| 18 |
+
"acc_norm,none": 0.31607744107744107,
|
| 19 |
+
"acc_norm_stderr,none": 0.009540440071928294
|
| 20 |
+
},
|
| 21 |
+
"arc_challenge": {
|
| 22 |
+
"name": "arc_challenge",
|
| 23 |
+
"alias": "arc_challenge",
|
| 24 |
+
"sample_len": 1172,
|
| 25 |
+
"acc,none": 0.17235494880546076,
|
| 26 |
+
"acc_stderr,none": 0.011037113093461295,
|
| 27 |
+
"acc_norm,none": 0.2098976109215017,
|
| 28 |
+
"acc_norm_stderr,none": 0.011900548748047421
|
| 29 |
+
},
|
| 30 |
+
"piqa": {
|
| 31 |
+
"name": "piqa",
|
| 32 |
+
"alias": "piqa",
|
| 33 |
+
"sample_len": 1838,
|
| 34 |
+
"acc,none": 0.5565832426550599,
|
| 35 |
+
"acc_stderr,none": 0.011590883373666865,
|
| 36 |
+
"acc_norm,none": 0.529923830250272,
|
| 37 |
+
"acc_norm_stderr,none": 0.011644913435420158
|
| 38 |
+
}
|
| 39 |
+
},
|
| 40 |
+
"group_subtasks": {},
|
| 41 |
+
"configs": {
|
| 42 |
+
"arc_challenge": {
|
| 43 |
+
"task": "arc_challenge",
|
| 44 |
+
"dataset_path": "allenai/ai2_arc",
|
| 45 |
+
"dataset_name": "ARC-Challenge",
|
| 46 |
+
"training_split": "train",
|
| 47 |
+
"validation_split": "validation",
|
| 48 |
+
"test_split": "test",
|
| 49 |
+
"doc_to_text": "Question: {{question}}\nAnswer:",
|
| 50 |
+
"doc_to_target": "{{choices.label.index(answerKey)}}",
|
| 51 |
+
"unsafe_code": false,
|
| 52 |
+
"doc_to_choice": "{{choices.text}}",
|
| 53 |
+
"description": "",
|
| 54 |
+
"target_delimiter": " ",
|
| 55 |
+
"fewshot_delimiter": "\n\n",
|
| 56 |
+
"fewshot_config": {
|
| 57 |
+
"sampler": "default",
|
| 58 |
+
"split": null,
|
| 59 |
+
"process_docs": null,
|
| 60 |
+
"fewshot_indices": null,
|
| 61 |
+
"samples": null,
|
| 62 |
+
"doc_to_text": "Question: {{question}}\nAnswer:",
|
| 63 |
+
"doc_to_choice": "{{choices.text}}",
|
| 64 |
+
"doc_to_target": "{{choices.label.index(answerKey)}}",
|
| 65 |
+
"gen_prefix": null,
|
| 66 |
+
"fewshot_delimiter": "\n\n",
|
| 67 |
+
"target_delimiter": " "
|
| 68 |
+
},
|
| 69 |
+
"num_fewshot": 0,
|
| 70 |
+
"metric_list": [
|
| 71 |
+
{
|
| 72 |
+
"metric": "acc",
|
| 73 |
+
"aggregation": "mean",
|
| 74 |
+
"higher_is_better": true
|
| 75 |
+
},
|
| 76 |
+
{
|
| 77 |
+
"metric": "acc_norm",
|
| 78 |
+
"aggregation": "mean",
|
| 79 |
+
"higher_is_better": true
|
| 80 |
+
}
|
| 81 |
+
],
|
| 82 |
+
"output_type": "multiple_choice",
|
| 83 |
+
"repeats": 1,
|
| 84 |
+
"should_decontaminate": true,
|
| 85 |
+
"doc_to_decontamination_query": "Question: {{question}}\nAnswer:",
|
| 86 |
+
"metadata": {
|
| 87 |
+
"version": 1.0,
|
| 88 |
+
"pretrained": ".",
|
| 89 |
+
"trust_remote_code": true,
|
| 90 |
+
"dtype": "bfloat16",
|
| 91 |
+
"max_length": 548,
|
| 92 |
+
"config_source": "/home/max/PROJECTS/PythonProjects/mcpterm/venv/lib/python3.11/site-packages/lm_eval/tasks/arc/arc_challenge.yaml"
|
| 93 |
+
}
|
| 94 |
+
},
|
| 95 |
+
"arc_easy": {
|
| 96 |
+
"task": "arc_easy",
|
| 97 |
+
"dataset_path": "allenai/ai2_arc",
|
| 98 |
+
"dataset_name": "ARC-Easy",
|
| 99 |
+
"training_split": "train",
|
| 100 |
+
"validation_split": "validation",
|
| 101 |
+
"test_split": "test",
|
| 102 |
+
"doc_to_text": "Question: {{question}}\nAnswer:",
|
| 103 |
+
"doc_to_target": "{{choices.label.index(answerKey)}}",
|
| 104 |
+
"unsafe_code": false,
|
| 105 |
+
"doc_to_choice": "{{choices.text}}",
|
| 106 |
+
"description": "",
|
| 107 |
+
"target_delimiter": " ",
|
| 108 |
+
"fewshot_delimiter": "\n\n",
|
| 109 |
+
"fewshot_config": {
|
| 110 |
+
"sampler": "default",
|
| 111 |
+
"split": null,
|
| 112 |
+
"process_docs": null,
|
| 113 |
+
"fewshot_indices": null,
|
| 114 |
+
"samples": null,
|
| 115 |
+
"doc_to_text": "Question: {{question}}\nAnswer:",
|
| 116 |
+
"doc_to_choice": "{{choices.text}}",
|
| 117 |
+
"doc_to_target": "{{choices.label.index(answerKey)}}",
|
| 118 |
+
"gen_prefix": null,
|
| 119 |
+
"fewshot_delimiter": "\n\n",
|
| 120 |
+
"target_delimiter": " "
|
| 121 |
+
},
|
| 122 |
+
"num_fewshot": 0,
|
| 123 |
+
"metric_list": [
|
| 124 |
+
{
|
| 125 |
+
"metric": "acc",
|
| 126 |
+
"aggregation": "mean",
|
| 127 |
+
"higher_is_better": true
|
| 128 |
+
},
|
| 129 |
+
{
|
| 130 |
+
"metric": "acc_norm",
|
| 131 |
+
"aggregation": "mean",
|
| 132 |
+
"higher_is_better": true
|
| 133 |
+
}
|
| 134 |
+
],
|
| 135 |
+
"output_type": "multiple_choice",
|
| 136 |
+
"repeats": 1,
|
| 137 |
+
"should_decontaminate": true,
|
| 138 |
+
"doc_to_decontamination_query": "Question: {{question}}\nAnswer:",
|
| 139 |
+
"metadata": {
|
| 140 |
+
"version": 1.0,
|
| 141 |
+
"pretrained": ".",
|
| 142 |
+
"trust_remote_code": true,
|
| 143 |
+
"dtype": "bfloat16",
|
| 144 |
+
"max_length": 548,
|
| 145 |
+
"config_source": "/home/max/PROJECTS/PythonProjects/mcpterm/venv/lib/python3.11/site-packages/lm_eval/tasks/arc/arc_easy.yaml"
|
| 146 |
+
}
|
| 147 |
+
},
|
| 148 |
+
"hellaswag": {
|
| 149 |
+
"task": "hellaswag",
|
| 150 |
+
"dataset_path": "Rowan/hellaswag",
|
| 151 |
+
"training_split": "train",
|
| 152 |
+
"validation_split": "validation",
|
| 153 |
+
"process_docs": "def process_docs(dataset: datasets.Dataset) -> datasets.Dataset:\n def _process_doc(doc):\n ctx = doc[\"ctx_a\"] + \" \" + doc[\"ctx_b\"].capitalize()\n out_doc = {\n \"query\": preprocess(doc[\"activity_label\"] + \": \" + ctx),\n \"choices\": [preprocess(ending) for ending in doc[\"endings\"]],\n \"gold\": int(doc[\"label\"]),\n }\n return out_doc\n\n return dataset.map(_process_doc)\n",
|
| 154 |
+
"doc_to_text": "{{query}}",
|
| 155 |
+
"doc_to_target": "{{label}}",
|
| 156 |
+
"unsafe_code": false,
|
| 157 |
+
"doc_to_choice": "choices",
|
| 158 |
+
"description": "",
|
| 159 |
+
"target_delimiter": " ",
|
| 160 |
+
"fewshot_delimiter": "\n\n",
|
| 161 |
+
"fewshot_config": {
|
| 162 |
+
"sampler": "default",
|
| 163 |
+
"split": null,
|
| 164 |
+
"process_docs": "<function process_docs at 0x77bb53ff80e0>",
|
| 165 |
+
"fewshot_indices": null,
|
| 166 |
+
"samples": null,
|
| 167 |
+
"doc_to_text": "{{query}}",
|
| 168 |
+
"doc_to_choice": "choices",
|
| 169 |
+
"doc_to_target": "{{label}}",
|
| 170 |
+
"gen_prefix": null,
|
| 171 |
+
"fewshot_delimiter": "\n\n",
|
| 172 |
+
"target_delimiter": " "
|
| 173 |
+
},
|
| 174 |
+
"num_fewshot": 0,
|
| 175 |
+
"metric_list": [
|
| 176 |
+
{
|
| 177 |
+
"metric": "acc",
|
| 178 |
+
"aggregation": "mean",
|
| 179 |
+
"higher_is_better": true
|
| 180 |
+
},
|
| 181 |
+
{
|
| 182 |
+
"metric": "acc_norm",
|
| 183 |
+
"aggregation": "mean",
|
| 184 |
+
"higher_is_better": true
|
| 185 |
+
}
|
| 186 |
+
],
|
| 187 |
+
"output_type": "multiple_choice",
|
| 188 |
+
"repeats": 1,
|
| 189 |
+
"should_decontaminate": false,
|
| 190 |
+
"metadata": {
|
| 191 |
+
"version": 1.0,
|
| 192 |
+
"pretrained": ".",
|
| 193 |
+
"trust_remote_code": true,
|
| 194 |
+
"dtype": "bfloat16",
|
| 195 |
+
"max_length": 548,
|
| 196 |
+
"config_source": "/home/max/PROJECTS/PythonProjects/mcpterm/venv/lib/python3.11/site-packages/lm_eval/tasks/hellaswag/hellaswag.yaml"
|
| 197 |
+
}
|
| 198 |
+
},
|
| 199 |
+
"piqa": {
|
| 200 |
+
"task": "piqa",
|
| 201 |
+
"dataset_path": "baber/piqa",
|
| 202 |
+
"training_split": "train",
|
| 203 |
+
"validation_split": "validation",
|
| 204 |
+
"doc_to_text": "Question: {{goal}}\nAnswer:",
|
| 205 |
+
"doc_to_target": "label",
|
| 206 |
+
"unsafe_code": false,
|
| 207 |
+
"doc_to_choice": "{{[sol1, sol2]}}",
|
| 208 |
+
"description": "",
|
| 209 |
+
"target_delimiter": " ",
|
| 210 |
+
"fewshot_delimiter": "\n\n",
|
| 211 |
+
"fewshot_config": {
|
| 212 |
+
"sampler": "default",
|
| 213 |
+
"split": null,
|
| 214 |
+
"process_docs": null,
|
| 215 |
+
"fewshot_indices": null,
|
| 216 |
+
"samples": null,
|
| 217 |
+
"doc_to_text": "Question: {{goal}}\nAnswer:",
|
| 218 |
+
"doc_to_choice": "{{[sol1, sol2]}}",
|
| 219 |
+
"doc_to_target": "label",
|
| 220 |
+
"gen_prefix": null,
|
| 221 |
+
"fewshot_delimiter": "\n\n",
|
| 222 |
+
"target_delimiter": " "
|
| 223 |
+
},
|
| 224 |
+
"num_fewshot": 0,
|
| 225 |
+
"metric_list": [
|
| 226 |
+
{
|
| 227 |
+
"metric": "acc",
|
| 228 |
+
"aggregation": "mean",
|
| 229 |
+
"higher_is_better": true
|
| 230 |
+
},
|
| 231 |
+
{
|
| 232 |
+
"metric": "acc_norm",
|
| 233 |
+
"aggregation": "mean",
|
| 234 |
+
"higher_is_better": true
|
| 235 |
+
}
|
| 236 |
+
],
|
| 237 |
+
"output_type": "multiple_choice",
|
| 238 |
+
"repeats": 1,
|
| 239 |
+
"should_decontaminate": true,
|
| 240 |
+
"doc_to_decontamination_query": "goal",
|
| 241 |
+
"metadata": {
|
| 242 |
+
"version": 1.0,
|
| 243 |
+
"pretrained": ".",
|
| 244 |
+
"trust_remote_code": true,
|
| 245 |
+
"dtype": "bfloat16",
|
| 246 |
+
"max_length": 548,
|
| 247 |
+
"config_source": "/home/max/PROJECTS/PythonProjects/mcpterm/venv/lib/python3.11/site-packages/lm_eval/tasks/piqa/piqa.yaml"
|
| 248 |
+
}
|
| 249 |
+
}
|
| 250 |
+
},
|
| 251 |
+
"versions": {
|
| 252 |
+
"arc_challenge": 1.0,
|
| 253 |
+
"arc_easy": 1.0,
|
| 254 |
+
"hellaswag": 1.0,
|
| 255 |
+
"piqa": 1.0
|
| 256 |
+
},
|
| 257 |
+
"n-shot": {
|
| 258 |
+
"arc_challenge": 0,
|
| 259 |
+
"arc_easy": 0,
|
| 260 |
+
"hellaswag": 0,
|
| 261 |
+
"piqa": 0
|
| 262 |
+
},
|
| 263 |
+
"higher_is_better": {
|
| 264 |
+
"arc_challenge": {
|
| 265 |
+
"acc": true,
|
| 266 |
+
"acc_norm": true
|
| 267 |
+
},
|
| 268 |
+
"arc_easy": {
|
| 269 |
+
"acc": true,
|
| 270 |
+
"acc_norm": true
|
| 271 |
+
},
|
| 272 |
+
"hellaswag": {
|
| 273 |
+
"acc": true,
|
| 274 |
+
"acc_norm": true
|
| 275 |
+
},
|
| 276 |
+
"piqa": {
|
| 277 |
+
"acc": true,
|
| 278 |
+
"acc_norm": true
|
| 279 |
+
}
|
| 280 |
+
},
|
| 281 |
+
"n-samples": {
|
| 282 |
+
"hellaswag": {
|
| 283 |
+
"original": 10042,
|
| 284 |
+
"effective": 10042
|
| 285 |
+
},
|
| 286 |
+
"arc_easy": {
|
| 287 |
+
"original": 2376,
|
| 288 |
+
"effective": 2376
|
| 289 |
+
},
|
| 290 |
+
"arc_challenge": {
|
| 291 |
+
"original": 1172,
|
| 292 |
+
"effective": 1172
|
| 293 |
+
},
|
| 294 |
+
"piqa": {
|
| 295 |
+
"original": 1838,
|
| 296 |
+
"effective": 1838
|
| 297 |
+
}
|
| 298 |
+
},
|
| 299 |
+
"config": {
|
| 300 |
+
"model": "hf",
|
| 301 |
+
"model_args": {
|
| 302 |
+
"pretrained": ".",
|
| 303 |
+
"trust_remote_code": true,
|
| 304 |
+
"dtype": "bfloat16",
|
| 305 |
+
"max_length": 548
|
| 306 |
+
},
|
| 307 |
+
"model_num_parameters": 2738880,
|
| 308 |
+
"model_dtype": "torch.float32",
|
| 309 |
+
"model_revision": "main",
|
| 310 |
+
"model_sha": "",
|
| 311 |
+
"batch_size": "auto:1",
|
| 312 |
+
"batch_sizes": [
|
| 313 |
+
64
|
| 314 |
+
],
|
| 315 |
+
"device": "cuda:0",
|
| 316 |
+
"use_cache": null,
|
| 317 |
+
"limit": null,
|
| 318 |
+
"bootstrap_iters": 100000,
|
| 319 |
+
"gen_kwargs": {},
|
| 320 |
+
"random_seed": 0,
|
| 321 |
+
"numpy_seed": 1234,
|
| 322 |
+
"torch_seed": 1234,
|
| 323 |
+
"fewshot_seed": 1234
|
| 324 |
+
},
|
| 325 |
+
"git_hash": "f5846e8",
|
| 326 |
+
"date": 1783178146.3657796,
|
| 327 |
+
"pretty_env_info": "PyTorch version: 2.10.0+cu130\nIs debug build: False\nCUDA used to build PyTorch: 13.0\nROCM used to build PyTorch: N/A\n\nOS: Debian GNU/Linux 12 (bookworm) (x86_64)\nGCC version: (Debian 12.2.0-14+deb12u1) 12.2.0\nClang version: Could not collect\nCMake version: version 3.25.1\nLibc version: glibc-2.36\n\nPython version: 3.11.2 (main, Apr 8 2026, 01:58:00) [GCC 12.2.0] (64-bit runtime)\nPython platform: Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.36\nIs CUDA available: True\nCUDA runtime version: 13.2.51\nCUDA_MODULE_LOADING set to: \nGPU models and configuration: GPU 0: NVIDIA GeForce RTX 3080\nNvidia driver version: 596.36\ncuDNN version: Could not collect\nIs XPU available: False\nHIP runtime version: N/A\nMIOpen runtime version: N/A\nIs XNNPACK available: True\nCaching allocator config: N/A\n\nCPU:\nArchitecture: x86_64\nCPU op-mode(s): 32-bit, 64-bit\nAddress sizes: 48 bits physical, 48 bits virtual\nByte Order: Little Endian\nCPU(s): 12\nOn-line CPU(s) list: 0-11\nVendor ID: AuthenticAMD\nModel name: AMD Ryzen 5 7500F 6-Core Processor\nCPU family: 25\nModel: 97\nThread(s) per core: 2\nCore(s) per socket: 6\nSocket(s): 1\nStepping: 2\nBogoMIPS: 7399.82\nFlags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology tsc_reliable nonstop_tsc cpuid extd_apicid tsc_known_freq pni pclmulqdq ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm cmp_legacy svm cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw topoext perfctr_core ssbd ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves avx512_bf16 clzero xsaveerptr arat npt nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avx512vbmi umip avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid fsrm\nVirtualization: AMD-V\nHypervisor vendor: Microsoft\nVirtualization type: full\nL1d cache: 192 KiB (6 instances)\nL1i cache: 192 KiB (6 instances)\nL2 cache: 6 MiB (6 instances)\nL3 cache: 32 MiB (1 instance)\nNUMA node(s): 1\nNUMA node0 CPU(s): 0-11\nVulnerability Gather data sampling: Not affected\nVulnerability Ghostwrite: Not affected\nVulnerability Indirect target selection: Not affected\nVulnerability Itlb multihit: Not affected\nVulnerability L1tf: Not affected\nVulnerability Mds: Not affected\nVulnerability Meltdown: Not affected\nVulnerability Mmio stale data: Not affected\nVulnerability Old microcode: Not affected\nVulnerability Reg file data sampling: Not affected\nVulnerability Retbleed: Not affected\nVulnerability Spec rstack overflow: Vulnerable: Safe RET, no microcode\nVulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl\nVulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization\nVulnerability Spectre v2: Mitigation; Retpolines; IBPB conditional; IBRS_FW; STIBP always-on; RSB filling; PBRSB-eIBRS Not affected; BHI Not affected\nVulnerability Srbds: Not affected\nVulnerability Tsa: Vulnerable: No microcode\nVulnerability Tsx async abort: Not affected\nVulnerability Vmscape: Not affected\n\nVersions of relevant libraries:\n[pip3] flash_attn==2.8.3+cu130torch2.10\n[pip3] mypy_extensions==1.1.0\n[pip3] numpy==2.2.6\n[pip3] nvidia-cublas==13.1.0.3\n[pip3] nvidia-cublas-cu12==12.8.4.1\n[pip3] nvidia-cuda-cupti==13.0.85\n[pip3] nvidia-cuda-cupti-cu12==12.8.90\n[pip3] nvidia-cuda-nvrtc==13.0.88\n[pip3] nvidia-cuda-nvrtc-cu12==12.8.93\n[pip3] nvidia-cuda-runtime==13.0.96\n[pip3] nvidia-cuda-runtime-cu12==12.8.90\n[pip3] nvidia-cudnn-cu12==9.10.2.21\n[pip3] nvidia-cudnn-cu13==9.15.1.9\n[pip3] nvidia-cudnn-frontend==1.18.0\n[pip3] nvidia-cufft==12.0.0.61\n[pip3] nvidia-cufft-cu12==11.3.3.83\n[pip3] nvidia-curand==10.4.0.35\n[pip3] nvidia-curand-cu12==10.3.9.90\n[pip3] nvidia-cusolver==12.0.4.66\n[pip3] nvidia-cusolver-cu12==11.7.3.90\n[pip3] nvidia-cusparse==12.6.3.3\n[pip3] nvidia-cusparse-cu12==12.5.8.93\n[pip3] nvidia-cusparselt-cu12==0.7.1\n[pip3] nvidia-cusparselt-cu13==0.8.0\n[pip3] nvidia-nccl-cu12==2.27.5\n[pip3] nvidia-nccl-cu13==2.28.9\n[pip3] nvidia-nvjitlink==13.0.88\n[pip3] nvidia-nvjitlink-cu12==12.8.93\n[pip3] nvidia-nvtx==13.0.85\n[pip3] nvidia-nvtx-cu12==12.8.90\n[pip3] onnxruntime==1.20.1\n[pip3] rapidocr-onnxruntime==1.4.4\n[pip3] rotary-embedding-torch==0.8.8\n[pip3] torch==2.10.0+cu130\n[pip3] torch_c_dlpack_ext==0.1.5\n[pip3] torch-lr-finder==0.2.2\n[pip3] torch-tb-profiler==0.4.3\n[pip3] torchaudio==2.10.0+cu130\n[pip3] torchmetrics==1.9.0\n[pip3] torchvision==0.25.0+cu130\n[pip3] triton==3.6.0\n[conda] Could not collect",
|
| 328 |
+
"transformers_version": "4.57.6",
|
| 329 |
+
"lm_eval_version": "0.4.12",
|
| 330 |
+
"upper_git_hash": "f5846e8ab83c0da3653a1f7a04d470911c8f5065",
|
| 331 |
+
"tokenizer_pad_token": [
|
| 332 |
+
"<|pad|>",
|
| 333 |
+
"0"
|
| 334 |
+
],
|
| 335 |
+
"tokenizer_eos_token": [
|
| 336 |
+
"<|eos|>",
|
| 337 |
+
"2"
|
| 338 |
+
],
|
| 339 |
+
"tokenizer_bos_token": [
|
| 340 |
+
"<|bos|>",
|
| 341 |
+
"1"
|
| 342 |
+
],
|
| 343 |
+
"eot_token_id": 2,
|
| 344 |
+
"max_length": 548,
|
| 345 |
+
"task_hashes": {},
|
| 346 |
+
"model_source": "hf",
|
| 347 |
+
"model_name": ".",
|
| 348 |
+
"model_name_sanitized": ".",
|
| 349 |
+
"system_instruction": null,
|
| 350 |
+
"system_instruction_sha": null,
|
| 351 |
+
"fewshot_as_multiturn": null,
|
| 352 |
+
"chat_template": null,
|
| 353 |
+
"chat_template_sha": null,
|
| 354 |
+
"total_evaluation_time_seconds": "80.63422504799973"
|
| 355 |
+
}
|
tokenization_atom.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
"""Remote-code tokenizer for Atom
|
| 2 |
|
| 3 |
The tokenizer is intentionally HF-compatible: generic callers can use
|
| 4 |
``AutoTokenizer.from_pretrained(..., trust_remote_code=True)``. Arithmetic digit
|
|
|
|
| 1 |
+
"""Remote-code tokenizer for Atom GPT checkpoints.
|
| 2 |
|
| 3 |
The tokenizer is intentionally HF-compatible: generic callers can use
|
| 4 |
``AutoTokenizer.from_pretrained(..., trust_remote_code=True)``. Arithmetic digit
|
tokenizer_utils.py
CHANGED
|
@@ -28,7 +28,7 @@ MAX_OPERAND_ROLES = 9
|
|
| 28 |
|
| 29 |
|
| 30 |
@dataclass(frozen=True)
|
| 31 |
-
class
|
| 32 |
ids: list[int]
|
| 33 |
place_ids: list[int]
|
| 34 |
role_ids: list[int]
|
|
@@ -46,7 +46,7 @@ class FusionEncoding:
|
|
| 46 |
|
| 47 |
def __post_init__(self) -> None:
|
| 48 |
if not (len(self.ids) == len(self.place_ids) == len(self.role_ids)):
|
| 49 |
-
raise ValueError("
|
| 50 |
|
| 51 |
|
| 52 |
def build_tokenizer() -> Any:
|
|
@@ -56,10 +56,15 @@ def build_tokenizer() -> Any:
|
|
| 56 |
tokenizer = Tokenizer(models.BPE(unk_token="<|unk|>"))
|
| 57 |
tokenizer.pre_tokenizer = pre_tokenizers.Sequence(
|
| 58 |
[
|
|
|
|
|
|
|
| 59 |
pre_tokenizers.Split(
|
| 60 |
Regex(r"\s+|\d|[+\-*/=()]|[^\s\d+\-*/=()]+"),
|
| 61 |
behavior="isolated",
|
| 62 |
),
|
|
|
|
|
|
|
|
|
|
| 63 |
pre_tokenizers.ByteLevel(add_prefix_space=False, use_regex=False),
|
| 64 |
]
|
| 65 |
)
|
|
@@ -67,7 +72,7 @@ def build_tokenizer() -> Any:
|
|
| 67 |
return tokenizer
|
| 68 |
|
| 69 |
|
| 70 |
-
class
|
| 71 |
"""Runtime wrapper adding LSD-first digit streams to a trained BPE tokenizer."""
|
| 72 |
|
| 73 |
_digit_span_re = re.compile(r"\d+")
|
|
@@ -85,11 +90,14 @@ class FusionTokenizer:
|
|
| 85 |
if self.tokenizer.token_to_id(digit) is not None
|
| 86 |
}
|
| 87 |
self._equals_id = self.tokenizer.token_to_id("=")
|
|
|
|
| 88 |
self._special_token_ids = frozenset(
|
| 89 |
token_id
|
| 90 |
for token in SPECIAL_TOKENS
|
| 91 |
if (token_id := self.tokenizer.token_to_id(token)) is not None
|
| 92 |
)
|
|
|
|
|
|
|
| 93 |
if len(self._digit_token_ids) != 10:
|
| 94 |
raise ValueError("Tokenizer vocabulary must contain atomic digit tokens 0-9")
|
| 95 |
if self._equals_id is None:
|
|
@@ -123,20 +131,31 @@ class FusionTokenizer:
|
|
| 123 |
return cls._digit_span_re.sub(lambda match: match.group(0)[::-1], text)
|
| 124 |
|
| 125 |
def _decode_token_piece(self, token_id: int) -> str:
|
| 126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
|
| 128 |
@staticmethod
|
| 129 |
def _is_equation_whitespace(piece: str) -> bool:
|
| 130 |
return bool(piece) and piece.isspace() and "\n" not in piece and "\r" not in piece
|
| 131 |
|
| 132 |
def _is_equation_piece(self, token_id: int, piece: str) -> bool:
|
|
|
|
|
|
|
|
|
|
| 133 |
if token_id in self._special_token_ids:
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
|
|
|
|
|
|
|
|
|
| 140 |
|
| 141 |
def _annotate_equation_span(
|
| 142 |
self,
|
|
@@ -213,20 +232,25 @@ class FusionTokenizer:
|
|
| 213 |
|
| 214 |
return place_ids, role_ids
|
| 215 |
|
| 216 |
-
def encode(self, text: str, *args, **kwargs) ->
|
| 217 |
transformed = self._reverse_digit_spans(text)
|
| 218 |
encoding = self.tokenizer.encode(transformed, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
| 219 |
ids = [int(token_id) for token_id in encoding.ids]
|
| 220 |
place_ids, role_ids = self.annotate_ids(ids)
|
| 221 |
-
return
|
| 222 |
ids=ids,
|
| 223 |
place_ids=place_ids,
|
| 224 |
role_ids=role_ids,
|
| 225 |
tokens=list(getattr(encoding, "tokens", [])),
|
| 226 |
)
|
| 227 |
|
| 228 |
-
def encode_batch(self, texts: list[str], *args, **kwargs) -> list[
|
| 229 |
-
|
|
|
|
|
|
|
| 230 |
|
| 231 |
def decode(
|
| 232 |
self,
|
|
@@ -293,15 +317,11 @@ def validate_tokenizer(tokenizer_dir: Path) -> None:
|
|
| 293 |
f"Missing {tokenizer_json}. Retrain with train_tokenizer.py so the "
|
| 294 |
"whitespace and digit boundary rules are preserved."
|
| 295 |
)
|
| 296 |
-
if vocab_path.exists():
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
tokenizer_data = json.load(f)
|
| 302 |
-
vocab = tokenizer_data.get("model", {}).get("vocab")
|
| 303 |
-
if not isinstance(vocab, dict):
|
| 304 |
-
raise FileNotFoundError(f"Missing vocab.json and no embedded vocab in {tokenizer_json}")
|
| 305 |
|
| 306 |
max_id = max(vocab.values())
|
| 307 |
if max_id > 65_535:
|
|
@@ -325,4 +345,4 @@ def load_tokenizer(tokenizer_dir: Path) -> Any:
|
|
| 325 |
|
| 326 |
validate_tokenizer(tokenizer_dir)
|
| 327 |
tokenizer_json, _, _ = tokenizer_files(tokenizer_dir)
|
| 328 |
-
return
|
|
|
|
| 28 |
|
| 29 |
|
| 30 |
@dataclass(frozen=True)
|
| 31 |
+
class AtomEncoding:
|
| 32 |
ids: list[int]
|
| 33 |
place_ids: list[int]
|
| 34 |
role_ids: list[int]
|
|
|
|
| 46 |
|
| 47 |
def __post_init__(self) -> None:
|
| 48 |
if not (len(self.ids) == len(self.place_ids) == len(self.role_ids)):
|
| 49 |
+
raise ValueError("Atom tokenizer streams must have equal length")
|
| 50 |
|
| 51 |
|
| 52 |
def build_tokenizer() -> Any:
|
|
|
|
| 56 |
tokenizer = Tokenizer(models.BPE(unk_token="<|unk|>"))
|
| 57 |
tokenizer.pre_tokenizer = pre_tokenizers.Sequence(
|
| 58 |
[
|
| 59 |
+
# BPE may merge within one of these spans, but never across them.
|
| 60 |
+
# This keeps whitespace, digits, and arithmetic syntax isolated.
|
| 61 |
pre_tokenizers.Split(
|
| 62 |
Regex(r"\s+|\d|[+\-*/=()]|[^\s\d+\-*/=()]+"),
|
| 63 |
behavior="isolated",
|
| 64 |
),
|
| 65 |
+
# Convert every span to bytes without applying GPT-2's prefix-space
|
| 66 |
+
# regex. The complete byte alphabet supplied to the trainer provides
|
| 67 |
+
# lossless fallback for arbitrary UTF-8 input.
|
| 68 |
pre_tokenizers.ByteLevel(add_prefix_space=False, use_regex=False),
|
| 69 |
]
|
| 70 |
)
|
|
|
|
| 72 |
return tokenizer
|
| 73 |
|
| 74 |
|
| 75 |
+
class AtomTokenizer:
|
| 76 |
"""Runtime wrapper adding LSD-first digit streams to a trained BPE tokenizer."""
|
| 77 |
|
| 78 |
_digit_span_re = re.compile(r"\d+")
|
|
|
|
| 90 |
if self.tokenizer.token_to_id(digit) is not None
|
| 91 |
}
|
| 92 |
self._equals_id = self.tokenizer.token_to_id("=")
|
| 93 |
+
self._arithmetic_token_texts = set(ARITHMETIC_TOKENS)
|
| 94 |
self._special_token_ids = frozenset(
|
| 95 |
token_id
|
| 96 |
for token in SPECIAL_TOKENS
|
| 97 |
if (token_id := self.tokenizer.token_to_id(token)) is not None
|
| 98 |
)
|
| 99 |
+
self._piece_cache: dict[int, str] = {}
|
| 100 |
+
self._equation_piece_cache: dict[int, bool] = {}
|
| 101 |
if len(self._digit_token_ids) != 10:
|
| 102 |
raise ValueError("Tokenizer vocabulary must contain atomic digit tokens 0-9")
|
| 103 |
if self._equals_id is None:
|
|
|
|
| 131 |
return cls._digit_span_re.sub(lambda match: match.group(0)[::-1], text)
|
| 132 |
|
| 133 |
def _decode_token_piece(self, token_id: int) -> str:
|
| 134 |
+
token_id = int(token_id)
|
| 135 |
+
piece = self._piece_cache.get(token_id)
|
| 136 |
+
if piece is None:
|
| 137 |
+
piece = self.tokenizer.decode([token_id], skip_special_tokens=False)
|
| 138 |
+
self._piece_cache[token_id] = piece
|
| 139 |
+
return piece
|
| 140 |
|
| 141 |
@staticmethod
|
| 142 |
def _is_equation_whitespace(piece: str) -> bool:
|
| 143 |
return bool(piece) and piece.isspace() and "\n" not in piece and "\r" not in piece
|
| 144 |
|
| 145 |
def _is_equation_piece(self, token_id: int, piece: str) -> bool:
|
| 146 |
+
cached = self._equation_piece_cache.get(token_id)
|
| 147 |
+
if cached is not None:
|
| 148 |
+
return cached
|
| 149 |
if token_id in self._special_token_ids:
|
| 150 |
+
result = False
|
| 151 |
+
elif token_id in self._digit_token_ids:
|
| 152 |
+
result = True
|
| 153 |
+
elif self._is_equation_whitespace(piece):
|
| 154 |
+
result = True
|
| 155 |
+
else:
|
| 156 |
+
result = len(piece) == 1 and piece in self._arithmetic_token_texts
|
| 157 |
+
self._equation_piece_cache[token_id] = result
|
| 158 |
+
return result
|
| 159 |
|
| 160 |
def _annotate_equation_span(
|
| 161 |
self,
|
|
|
|
| 232 |
|
| 233 |
return place_ids, role_ids
|
| 234 |
|
| 235 |
+
def encode(self, text: str, *args, **kwargs) -> AtomEncoding:
|
| 236 |
transformed = self._reverse_digit_spans(text)
|
| 237 |
encoding = self.tokenizer.encode(transformed, *args, **kwargs)
|
| 238 |
+
return self._wrap_encoding(encoding)
|
| 239 |
+
|
| 240 |
+
def _wrap_encoding(self, encoding: Any) -> AtomEncoding:
|
| 241 |
ids = [int(token_id) for token_id in encoding.ids]
|
| 242 |
place_ids, role_ids = self.annotate_ids(ids)
|
| 243 |
+
return AtomEncoding(
|
| 244 |
ids=ids,
|
| 245 |
place_ids=place_ids,
|
| 246 |
role_ids=role_ids,
|
| 247 |
tokens=list(getattr(encoding, "tokens", [])),
|
| 248 |
)
|
| 249 |
|
| 250 |
+
def encode_batch(self, texts: list[str], *args, **kwargs) -> list[AtomEncoding]:
|
| 251 |
+
transformed = [self._reverse_digit_spans(text) for text in texts]
|
| 252 |
+
encodings = self.tokenizer.encode_batch(transformed, *args, **kwargs)
|
| 253 |
+
return [self._wrap_encoding(encoding) for encoding in encodings]
|
| 254 |
|
| 255 |
def decode(
|
| 256 |
self,
|
|
|
|
| 317 |
f"Missing {tokenizer_json}. Retrain with train_tokenizer.py so the "
|
| 318 |
"whitespace and digit boundary rules are preserved."
|
| 319 |
)
|
| 320 |
+
if not vocab_path.exists() or not merges_path.exists():
|
| 321 |
+
raise FileNotFoundError(f"Missing vocab.json or merges.txt in {tokenizer_dir}")
|
| 322 |
+
|
| 323 |
+
with vocab_path.open("r", encoding="utf-8") as f:
|
| 324 |
+
vocab = json.load(f)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 325 |
|
| 326 |
max_id = max(vocab.values())
|
| 327 |
if max_id > 65_535:
|
|
|
|
| 345 |
|
| 346 |
validate_tokenizer(tokenizer_dir)
|
| 347 |
tokenizer_json, _, _ = tokenizer_files(tokenizer_dir)
|
| 348 |
+
return AtomTokenizer(Tokenizer.from_file(str(tokenizer_json)))
|