1use memra_gguf::GgufFile;
2use memra_gguf::config::{HfConfig, ModelConfig};
3use memra_gguf::model_packs::{self, Gate, ModelPack, TokenizerSource};
4use memra_gguf::placement::{LayerPlacementCost, PlacementRequest, plan_contiguous_stages};
5use memra_gguf::safetensors::{
6 StInfo, StModel, parse_header_json_checked, parse_index_weight_map_json_checked,
7};
8#[cfg(test)]
9use memra_gguf::source::canonical_hf_name;
10use memra_gguf::source::{
11 Hy3RepackSource, TensorCensusRecord, TensorSource, census_from_gguf,
12 census_from_safetensors_headers,
13};
14use memra_gguf::tensor_contract::{
15 BoundTensorContract, CheckpointDialect, ContractOptions, OutputHead, TensorId, TensorOwner,
16};
17use memra_reference::{deterministic_fixture, execute, execute_multimodal, execute_vision};
18use sha2::{Digest, Sha256};
19use std::collections::BTreeMap;
20use std::fmt::Write as _;
21use std::io::Write as _;
22use std::path::{Path, PathBuf};
23use std::process::{Command, Output, Stdio};
24
25const MAX_TEXT_BYTES: usize = 100_000_000;
26
27pub struct InspectRequest {
28 pub source: String,
29 pub against: String,
30 pub out_dir: PathBuf,
31}
32
33pub struct InspectSummary {
34 pub family: &'static str,
35 pub tensor_count: usize,
36 pub out_dir: PathBuf,
37}
38
39pub struct ScaffoldRequest {
40 pub family: String,
41 pub out_dir: PathBuf,
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
45pub enum VerifyStage {
46 Config,
47 Tiny,
48 Checkpoint,
49 Rewrite,
50 Serve,
51}
52
53pub struct VerifyRequest {
54 pub stage: VerifyStage,
55 pub source: String,
56 pub against: String,
57 pub out_dir: Option<PathBuf>,
58 pub oracle: Option<PathBuf>,
59 pub native_runner: Option<PathBuf>,
60}
61
62pub struct VerifySummary {
63 pub family: &'static str,
64 pub stage: VerifyStage,
65}
66
67pub fn verify_model(request: VerifyRequest) -> Result<VerifySummary, Box<dyn std::error::Error>> {
68 match request.stage {
69 VerifyStage::Config => {
70 let pack = model_packs::by_alias(&request.against)
71 .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
72 let config = load_config_only(&request.source)?;
73 pack.compile_plan(&config)?;
74 Ok(VerifySummary {
75 family: pack.family,
76 stage: VerifyStage::Config,
77 })
78 }
79 VerifyStage::Checkpoint => {
80 let pack = model_packs::by_alias(&request.against)
81 .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
82 let out_dir = request.out_dir.ok_or("verify checkpoint requires --out")?;
83 let summary = inspect_model(InspectRequest {
84 source: request.source.clone(),
85 against: request.against.clone(),
86 out_dir: out_dir.clone(),
87 })?;
88 write_hf_oracle_bundle(&request.source, &out_dir)?;
89 let gate = pack.checkpoint_parity.ok_or_else(|| {
90 format!(
91 "model pack {} has no checkpoint parity threshold; capture bundle written to {} and no fallback is allowed",
92 pack.family,
93 out_dir.display()
94 )
95 })?;
96 let oracle_path = request.oracle.ok_or_else(|| {
97 format!(
98 "checkpoint tensor contract passed; run {} offline, then repeat with --oracle <hf-oracle.tsv>; no fallback is allowed",
99 out_dir.join("capture-hf-oracle.py").display()
100 )
101 })?;
102 let runner = request
103 .native_runner
104 .or_else(|| std::env::var_os("MEMRA_NATIVE_CHECKPOINT_RUNNER").map(PathBuf::from))
105 .ok_or("checkpoint parity requires --native-runner or MEMRA_NATIVE_CHECKPOINT_RUNNER; no fallback is allowed")?;
106 let native_path = out_dir.join("native-oracle.tsv");
107 run_native_checkpoint(&runner, &request.source, &native_path)?;
108 let runner_hash = hex_sha256(&std::fs::read(&runner)?);
109 let expected = parse_checkpoint_oracle(&std::fs::read_to_string(&oracle_path)?)?;
110 let actual = parse_checkpoint_oracle(&std::fs::read_to_string(&native_path)?)?;
111 let receipt = match compare_checkpoint_oracles(&expected, &actual, gate) {
112 Ok(receipt) => receipt,
113 Err(error) => {
114 write_atomic(
115 &out_dir.join("checkpoint-parity.tsv"),
116 format!(
117 "status\tfailed\nerror\t{}\n",
118 lock_value(&error.to_string())
119 )
120 .as_bytes(),
121 )?;
122 write_atomic(
123 &out_dir.join("gates.txt"),
124 format_gate_results_with_receipts(
125 pack,
126 &out_dir,
127 &[Gate::Config, Gate::TokenizerTemplate, Gate::TensorCensus],
128 &[Gate::CheckpointParity],
129 )
130 .as_bytes(),
131 )?;
132 return Err(error);
133 }
134 };
135 let artifact_lock = std::fs::read(out_dir.join("artifact.lock"))?;
136 let receipt = format!(
137 "{receipt}artifact_lock_sha256\t{}\nnative_runner_sha256\t{runner_hash}\n",
138 hex_sha256(&artifact_lock)
139 );
140 write_atomic(&out_dir.join("checkpoint-parity.tsv"), receipt.as_bytes())?;
141 write_atomic(
142 &out_dir.join("gates.txt"),
143 format_gate_results_with_receipts(
144 pack,
145 &out_dir,
146 &[
147 Gate::Config,
148 Gate::TokenizerTemplate,
149 Gate::TensorCensus,
150 Gate::CheckpointParity,
151 ],
152 &[],
153 )
154 .as_bytes(),
155 )?;
156 Ok(VerifySummary {
157 family: summary.family,
158 stage: VerifyStage::Checkpoint,
159 })
160 }
161 VerifyStage::Tiny => {
162 let pack = model_packs::by_alias(&request.against)
163 .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
164 if pack.support.is_none() {
165 return Err(format!(
166 "model pack {} is inspect-only and has no native support state",
167 pack.family
168 )
169 .into());
170 }
171 let out_dir = request.out_dir.ok_or("verify tiny requires --out")?;
172 let plan = pack.compile_tiny_plan()?;
173 let fixture = deterministic_fixture(&plan)?;
174 let first = execute(&plan, &fixture.weights, &fixture.token_ids)?;
175 let second = execute(&plan, &fixture.weights, &fixture.token_ids)?;
176 if first != second {
177 return Err("native reference fixture is not bit-deterministic".into());
178 }
179 let vision = fixture
180 .vision
181 .as_ref()
182 .map(|input| {
183 let first = execute_vision(&plan, &fixture.weights, input)?;
184 let second = execute_vision(&plan, &fixture.weights, input)?;
185 if first != second {
186 return Err(ReferenceVisionError::Nondeterministic);
187 }
188 Ok(first)
189 })
190 .transpose()
191 .map_err(|error| -> Box<dyn std::error::Error> { error.into() })?;
192 let multimodal = match (
193 fixture.multimodal_token_ids.as_ref(),
194 fixture.vision.as_ref(),
195 ) {
196 (Some(token_ids), Some(input)) => {
197 let first = execute_multimodal(&plan, &fixture.weights, token_ids, input)?;
198 let second = execute_multimodal(&plan, &fixture.weights, token_ids, input)?;
199 if first != second {
200 return Err(
201 "native multimodal reference fixture is not bit-deterministic".into(),
202 );
203 }
204 Some(first)
205 }
206 (None, None) | (None, Some(_)) if plan.multimodal.is_none() => None,
207 _ => {
208 return Err(
209 "multimodal plan is missing its combined tiny fixture inputs".into(),
210 );
211 }
212 };
213 std::fs::create_dir_all(&out_dir)?;
214 write_atomic(
215 &out_dir.join("tiny-fixture.txt"),
216 format_tiny_fixture(&plan, &fixture).as_bytes(),
217 )?;
218 write_atomic(
219 &out_dir.join("reference-oracle.tsv"),
220 format_reference_oracle(&first).as_bytes(),
221 )?;
222 if let Some(vision) = vision.as_ref() {
223 write_atomic(
224 &out_dir.join("reference-vision-oracle.tsv"),
225 format_reference_vision_oracle(vision).as_bytes(),
226 )?;
227 }
228 if let Some(multimodal) = multimodal.as_ref() {
229 write_atomic(
230 &out_dir.join("reference-multimodal-oracle.tsv"),
231 format_reference_oracle(&multimodal.language).as_bytes(),
232 )?;
233 }
234 write_atomic(
235 &out_dir.join("tiny-gate.tsv"),
236 format!("status\tpassed\nfamily\t{}\n", pack.family).as_bytes(),
237 )?;
238 write_atomic(
239 &out_dir.join("gates.txt"),
240 format_gate_results_with_receipts(
241 pack,
242 &out_dir,
243 &[Gate::Config, Gate::TinyParity],
244 &[],
245 )
246 .as_bytes(),
247 )?;
248 Ok(VerifySummary {
249 family: pack.family,
250 stage: VerifyStage::Tiny,
251 })
252 }
253 VerifyStage::Rewrite => {
254 let pack = model_packs::by_alias(&request.against)
255 .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
256 let out_dir = request
257 .out_dir
258 .ok_or("verify rewrite requires --out; no fallback is allowed")?;
259 verify_rewrite_receipt(pack, Path::new(&request.source), &out_dir)?;
260 Ok(VerifySummary {
261 family: pack.family,
262 stage: VerifyStage::Rewrite,
263 })
264 }
265 VerifyStage::Serve => {
266 let pack = model_packs::by_alias(&request.against)
267 .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
268 let out_dir = request
269 .out_dir
270 .ok_or("verify serve requires --out; no fallback is allowed")?;
271 let runner = request
272 .native_runner
273 .or_else(|| std::env::var_os("MEMRA_NATIVE_SERVE_RUNNER").map(PathBuf::from))
274 .ok_or("verify serve requires --native-runner or MEMRA_NATIVE_SERVE_RUNNER; no fallback is allowed")?;
275 verify_native_serve(pack, &request.source, &out_dir, &runner)?;
276 Ok(VerifySummary {
277 family: pack.family,
278 stage: VerifyStage::Serve,
279 })
280 }
281 }
282}
283
284fn verify_rewrite_receipt(
285 pack: &ModelPack,
286 receipt_path: &Path,
287 out_dir: &Path,
288) -> Result<(), Box<dyn std::error::Error>> {
289 let artifact_lock = std::fs::read_to_string(out_dir.join("artifact.lock"))?;
290 let artifact_lock_sha256 = hex_sha256(artifact_lock.as_bytes());
291 if !artifact_lock
292 .lines()
293 .any(|line| line == format!("family={}", pack.family))
294 {
295 return Err("rewrite receipt family does not match artifact.lock".into());
296 }
297 let manifest = std::fs::read_to_string(out_dir.join("execution-rewrites.tsv"))?;
298 let receipt = std::fs::read_to_string(receipt_path)?;
299 let mut fields = BTreeMap::new();
300 for line in receipt.lines() {
301 let Some((key, value)) = line.split_once('\t') else {
302 return Err(format!("malformed rewrite receipt line {line:?}").into());
303 };
304 if fields.insert(key, value).is_some() {
305 return Err(format!("duplicate rewrite receipt field {key}").into());
306 }
307 }
308 for (key, expected) in [
309 ("format", "memra-rewrite-parity-v1"),
310 ("status", "passed"),
311 ("first_violation", "none"),
312 ] {
313 if fields.get(key).copied() != Some(expected) {
314 return Err(format!("rewrite receipt requires {key}={expected}").into());
315 }
316 }
317 match fields.get("value_kind").copied() {
318 Some("logits-f32") if fields.get("require_argmax").copied() == Some("true") => {}
319 Some("token-ids-u32") if fields.get("require_argmax").copied() == Some("false") => {}
320 _ => return Err("rewrite receipt has an invalid value_kind/argmax policy".into()),
321 }
322 let rewrite_id = *fields.get("rewrite").ok_or("rewrite receipt has no id")?;
323 let row = manifest
324 .lines()
325 .skip(1)
326 .find(|line| line.split('\t').next() == Some(rewrite_id))
327 .ok_or_else(|| format!("rewrite {rewrite_id} is absent from execution manifest"))?;
328 let columns: Vec<_> = row.split('\t').collect();
329 if columns.len() != 8 || columns[4] != "true" {
330 return Err(format!("rewrite {rewrite_id} is not eligible in this artifact").into());
331 }
332 for (field, expected) in [
333 ("surface", columns[1]),
334 ("implementation", columns[2]),
335 ("plan_sha256", columns[3]),
336 ] {
337 if fields.get(field).copied() != Some(expected) {
338 return Err(format!("rewrite receipt {field} does not match manifest").into());
339 }
340 }
341 if fields.get("artifact_lock_sha256").copied() != Some(artifact_lock_sha256.as_str()) {
342 return Err("rewrite receipt does not match artifact.lock".into());
343 }
344 let reference = fields
345 .get("reference_sha256")
346 .ok_or("rewrite receipt has no reference hash")?;
347 let candidate = fields
348 .get("candidate_sha256")
349 .ok_or("rewrite receipt has no candidate hash")?;
350 let parse_nonnegative = |field: &str| -> Result<f32, Box<dyn std::error::Error>> {
351 let value = fields
352 .get(field)
353 .ok_or_else(|| format!("rewrite receipt has no {field}"))?
354 .parse::<f32>()?;
355 if !value.is_finite() || value < 0.0 {
356 return Err(format!("rewrite receipt {field} is not finite and nonnegative").into());
357 }
358 Ok(value)
359 };
360 let atol = parse_nonnegative("atol")?;
361 let rtol = parse_nonnegative("rtol")?;
362 let max_abs = parse_nonnegative("max_abs")?;
363 let _max_rel = parse_nonnegative("max_rel")?;
364 if atol == 0.0 && rtol == 0.0 && (max_abs != 0.0 || reference != candidate) {
365 return Err("exact rewrite receipt has nonzero error or different stream hashes".into());
366 }
367 for field in [
368 "implementation_sha256",
369 "reference_sha256",
370 "candidate_sha256",
371 ] {
372 let value = fields[field];
373 if value.len() != 64
374 || !value
375 .bytes()
376 .all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte))
377 {
378 return Err(format!("rewrite receipt {field} is not a lowercase SHA-256").into());
379 }
380 }
381 if fields
382 .get("values")
383 .and_then(|value| value.parse::<usize>().ok())
384 .is_none_or(|values| values == 0)
385 {
386 return Err("rewrite receipt compared no values".into());
387 }
388 let receipt_hash = hex_sha256(receipt.as_bytes());
389 let receipt_dir = out_dir.join("rewrite-receipts");
390 std::fs::create_dir_all(&receipt_dir)?;
391 write_atomic(
392 &receipt_dir.join(format!("{rewrite_id}.tsv")),
393 receipt.as_bytes(),
394 )?;
395 let index_path = out_dir.join("rewrite-receipts.tsv");
396 let mut index = BTreeMap::new();
397 if let Ok(existing) = std::fs::read_to_string(&index_path) {
398 for line in existing.lines().skip(1) {
399 let columns: Vec<_> = line.split('\t').collect();
400 if columns.len() == 4 {
401 index.insert(
402 columns[0].to_string(),
403 (
404 columns[1].to_string(),
405 columns[2].to_string(),
406 columns[3].to_string(),
407 ),
408 );
409 }
410 }
411 }
412 index.insert(
413 rewrite_id.to_string(),
414 (columns[3].to_string(), receipt_hash, "passed".to_string()),
415 );
416 let mut index_text = String::from("rewrite\tplan_sha256\treceipt_sha256\tstatus\n");
417 for (rewrite, (plan, hash, status)) in index {
418 writeln!(index_text, "{rewrite}\t{plan}\t{hash}\t{status}").unwrap();
419 }
420 write_atomic(&index_path, index_text.as_bytes())?;
421 write_atomic(
422 &out_dir.join("gates.txt"),
423 format_gate_results_with_receipts(pack, out_dir, &[], &[]).as_bytes(),
424 )?;
425 Ok(())
426}
427
428fn verify_native_serve(
429 pack: &ModelPack,
430 source: &str,
431 out_dir: &Path,
432 runner: &Path,
433) -> Result<(), Box<dyn std::error::Error>> {
434 if !Path::new(source).exists() {
435 return Err("verify serve requires a local model artifact; no fallback is allowed".into());
436 }
437 let checkpoint_receipt = out_dir.join("checkpoint-parity.tsv");
438 let artifact_lock_path = out_dir.join("artifact.lock");
439 let artifact_lock = std::fs::read_to_string(&artifact_lock_path).map_err(|error| {
440 format!(
441 "verify serve requires {} from inspect/checkpoint first: {error}; no fallback is allowed",
442 artifact_lock_path.display()
443 )
444 })?;
445 if !artifact_lock
446 .lines()
447 .any(|line| line == format!("source={}", lock_value(source)))
448 || !artifact_lock.lines().any(|line| line == "binding=passed")
449 || !artifact_lock.lines().any(|line| line == "tokenizer=passed")
450 {
451 return Err(
452 "verify serve artifact.lock does not match this source with binding/tokenizer passed; no fallback is allowed"
453 .into(),
454 );
455 }
456 let checkpoint = std::fs::read_to_string(&checkpoint_receipt).map_err(|error| {
457 format!(
458 "verify serve requires a passed {} first: {error}; no fallback is allowed",
459 checkpoint_receipt.display()
460 )
461 })?;
462 if !checkpoint.lines().any(|line| line == "status\tpassed") {
463 return Err(
464 "verify serve requires status=passed checkpoint parity; no fallback is allowed".into(),
465 );
466 }
467 let lock_hash = hex_sha256(artifact_lock.as_bytes());
468 if !checkpoint
469 .lines()
470 .any(|line| line == format!("artifact_lock_sha256\t{lock_hash}"))
471 {
472 return Err(
473 "verify serve checkpoint receipt does not match artifact.lock; no fallback is allowed"
474 .into(),
475 );
476 }
477 std::fs::create_dir_all(out_dir)?;
478 let listener = std::net::TcpListener::bind("127.0.0.1:0")?;
479 let port = listener.local_addr()?.port();
480 drop(listener);
481 let address = format!("127.0.0.1:{port}");
482 let api_key = "memra-onboarding-verify";
483 let log_path = out_dir.join("serve.log");
484 let log = std::fs::File::create(&log_path)?;
485 let mut child = Command::new(runner)
486 .env("MEMRA_MODELS", format!("verify={source}"))
487 .env("MEMRA_REWRITE_BUNDLE", out_dir)
488 .env("MEMRA_ADDR", &address)
489 .env("MEMRA_API_KEY", api_key)
490 .stdin(Stdio::null())
491 .stdout(Stdio::from(log.try_clone()?))
492 .stderr(Stdio::from(log))
493 .spawn()?;
494 let result = (|| -> Result<String, Box<dyn std::error::Error>> {
495 let timeout = std::env::var("MEMRA_SERVE_VERIFY_TIMEOUT_S")
496 .ok()
497 .and_then(|value| value.parse::<u64>().ok())
498 .unwrap_or(180);
499 let started = std::time::Instant::now();
500 loop {
501 if let Some(status) = child.try_wait()? {
502 return Err(format!(
503 "native server exited before readiness with {status}; inspect {}",
504 log_path.display()
505 )
506 .into());
507 }
508 let ready = Command::new("curl")
509 .args([
510 "--fail",
511 "--silent",
512 "--output",
513 "/dev/null",
514 &format!("http://{address}/readyz"),
515 ])
516 .status();
517 if ready.is_ok_and(|status| status.success()) {
518 break;
519 }
520 if started.elapsed() >= std::time::Duration::from_secs(timeout) {
521 return Err(format!(
522 "native server did not become ready within {timeout}s; inspect {}",
523 log_path.display()
524 )
525 .into());
526 }
527 std::thread::sleep(std::time::Duration::from_millis(250));
528 }
529 let response = Command::new("curl")
530 .args([
531 "--fail",
532 "--silent",
533 "--show-error",
534 "--header",
535 &format!("Authorization: Bearer {api_key}"),
536 "--header",
537 "Content-Type: application/json",
538 "--data",
539 r#"{"model":"verify","prompt":"Hello","max_tokens":1,"temperature":0}"#,
540 &format!("http://{address}/v1/completions"),
541 ])
542 .output()?;
543 if !response.status.success() {
544 return Err(format!(
545 "native completion failed with {}: {}",
546 response.status,
547 String::from_utf8_lossy(&response.stderr)
548 )
549 .into());
550 }
551 let response = String::from_utf8(response.stdout)?;
552 if !response.contains("\"choices\"") || response.contains("\"error\"") {
553 return Err(format!("native completion response is not successful: {response}").into());
554 }
555 Ok(response)
556 })();
557 let _ = child.kill();
558 let _ = child.wait();
559 let response = result?;
560 let runner_hash = hex_sha256(&std::fs::read(runner)?);
561 write_atomic(&out_dir.join("serve-response.json"), response.as_bytes())?;
562 write_atomic(
563 &out_dir.join("serve-gate.tsv"),
564 format!(
565 "status\tpassed\nfamily\t{}\nmodel\tverify\nendpoint\t/v1/completions\nartifact_lock_sha256\t{lock_hash}\nnative_runner_sha256\t{runner_hash}\n",
566 pack.family,
567 )
568 .as_bytes(),
569 )?;
570 write_atomic(
571 &out_dir.join("gates.txt"),
572 format_gate_results_with_receipts(
573 pack,
574 out_dir,
575 &[
576 Gate::Config,
577 Gate::TokenizerTemplate,
578 Gate::TensorCensus,
579 Gate::CheckpointParity,
580 Gate::Serve,
581 ],
582 &[],
583 )
584 .as_bytes(),
585 )?;
586 Ok(())
587}
588
589#[derive(Debug, Clone, PartialEq)]
590struct CheckpointOracle {
591 engine: String,
592 numeric_class: String,
593 tokens: Vec<u32>,
594 vocab: usize,
595 logits: Vec<f32>,
596}
597
598fn write_hf_oracle_bundle(source: &str, out_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
599 let tokens = [1u32, 2, 3, 4];
600 let (model, revision) = if Path::new(source).exists() {
601 (source.to_string(), None)
602 } else {
603 let (model, revision) = parse_pinned_hf_source(source)?;
604 (model.to_string(), Some(revision.to_string()))
605 };
606 let request = format!(
607 "format\tmemra-checkpoint-request-v1\nsource\t{}\nrevision\t{}\nnumeric_class\tsource-weights-float32-accumulation\ntokens\t{}\n",
608 lock_value(&model),
609 revision.as_deref().unwrap_or("local"),
610 tokens
611 .iter()
612 .map(u32::to_string)
613 .collect::<Vec<_>>()
614 .join(",")
615 );
616 write_atomic(&out_dir.join("oracle-request.tsv"), request.as_bytes())?;
617 let model_literal = format!("{model:?}");
618 let revision_literal = revision
619 .as_ref()
620 .map(|revision| format!("{revision:?}"))
621 .unwrap_or_else(|| "None".to_string());
622 let script = format!(
623 r#"#!/usr/bin/env python3
624import argparse
625import struct
626import torch
627import transformers
628from transformers import AutoModelForCausalLM
629
630MODEL = {model_literal}
631REVISION = {revision_literal}
632TOKENS = [1, 2, 3, 4]
633
634parser = argparse.ArgumentParser(description="Offline HF correctness oracle for Memra onboarding")
635parser.add_argument("--out", default="hf-oracle.tsv")
636args = parser.parse_args()
637
638model = AutoModelForCausalLM.from_pretrained(
639 MODEL,
640 revision=REVISION,
641 dtype=torch.float32,
642 trust_remote_code=False,
643)
644device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
645model = model.to(device).eval()
646with torch.no_grad():
647 logits = model(input_ids=torch.tensor([TOKENS], device=device)).logits[0, -1].float().cpu()
648
649with open(args.out, "w", encoding="utf-8") as f:
650 f.write("format\tmemra-checkpoint-oracle-v1\n")
651 f.write("engine\thf-transformers-fp32\n")
652 f.write("numeric_class\tsource-weights-float32-accumulation\n")
653 f.write(f"transformers_version\t{{transformers.__version__}}\n")
654 f.write(f"torch_version\t{{torch.__version__}}\n")
655 f.write("tokens\t" + ",".join(map(str, TOKENS)) + "\n")
656 f.write(f"vocab\t{{logits.numel()}}\n")
657 for index, value in enumerate(logits.tolist()):
658 bits = struct.unpack("<I", struct.pack("<f", value))[0]
659 f.write(f"logit\t{{index}}\t{{bits:08x}}\n")
660"#
661 );
662 write_atomic(&out_dir.join("capture-hf-oracle.py"), script.as_bytes())?;
663 Ok(())
664}
665
666fn run_native_checkpoint(
667 runner: &Path,
668 source: &str,
669 output: &Path,
670) -> Result<(), Box<dyn std::error::Error>> {
671 if !Path::new(source).is_dir() {
672 return Err(
673 "native checkpoint parity requires a local safetensors directory; inspect may use a pinned remote header, execution may not"
674 .into(),
675 );
676 }
677 let result = Command::new(runner)
678 .arg(source)
679 .args(["1", "2", "3", "4"])
680 .env("MEMRA_FULL_PREC", "1")
681 .env("MEMRA_ORACLE_OUT", output)
682 .output()?;
683 if !result.status.success() {
684 return Err(format!(
685 "native checkpoint runner failed ({}): stdout={} stderr={}",
686 result.status,
687 String::from_utf8_lossy(&result.stdout),
688 String::from_utf8_lossy(&result.stderr)
689 )
690 .into());
691 }
692 if !output.is_file() {
693 return Err(format!(
694 "native checkpoint runner did not create {}",
695 output.display()
696 )
697 .into());
698 }
699 Ok(())
700}
701
702fn parse_checkpoint_oracle(text: &str) -> Result<CheckpointOracle, Box<dyn std::error::Error>> {
703 let mut format_ok = false;
704 let mut engine = None;
705 let mut numeric_class = None;
706 let mut tokens = None;
707 let mut vocab = None;
708 let mut logits = BTreeMap::new();
709 for line in text.lines() {
710 let fields: Vec<_> = line.split('\t').collect();
711 match fields.as_slice() {
712 ["format", "memra-checkpoint-oracle-v1"] => format_ok = true,
713 ["engine", value] => engine = Some((*value).to_string()),
714 ["numeric_class", value] => numeric_class = Some((*value).to_string()),
715 ["tokens", value] => {
716 tokens = Some(
717 value
718 .split(',')
719 .map(str::parse)
720 .collect::<Result<Vec<u32>, _>>()?,
721 )
722 }
723 ["vocab", value] => vocab = Some(value.parse::<usize>()?),
724 ["logit", index, bits] => {
725 let index = index.parse::<usize>()?;
726 let bits = u32::from_str_radix(bits, 16)?;
727 if logits.insert(index, f32::from_bits(bits)).is_some() {
728 return Err(format!("duplicate oracle logit index {index}").into());
729 }
730 }
731 _ => {}
732 }
733 }
734 if !format_ok {
735 return Err("oracle is missing format=memra-checkpoint-oracle-v1".into());
736 }
737 let vocab = vocab.ok_or("oracle is missing vocab")?;
738 if logits.len() != vocab || (0..vocab).any(|index| !logits.contains_key(&index)) {
739 return Err(format!(
740 "oracle has {} logits, expected contiguous {vocab}",
741 logits.len()
742 )
743 .into());
744 }
745 Ok(CheckpointOracle {
746 engine: engine.ok_or("oracle is missing engine")?,
747 numeric_class: numeric_class.ok_or("oracle is missing numeric_class")?,
748 tokens: tokens.ok_or("oracle is missing tokens")?,
749 vocab,
750 logits: (0..vocab).map(|index| logits[&index]).collect(),
751 })
752}
753
754fn compare_checkpoint_oracles(
755 expected: &CheckpointOracle,
756 actual: &CheckpointOracle,
757 gate: model_packs::CheckpointParityGate,
758) -> Result<String, Box<dyn std::error::Error>> {
759 if expected.numeric_class != actual.numeric_class {
760 return Err(format!(
761 "oracle numeric class mismatch: expected={} native={}",
762 expected.numeric_class, actual.numeric_class
763 )
764 .into());
765 }
766 if expected.tokens != actual.tokens || expected.vocab != actual.vocab {
767 return Err(format!(
768 "oracle identity mismatch: expected tokens={:?} vocab={}, native tokens={:?} vocab={}",
769 expected.tokens, expected.vocab, actual.tokens, actual.vocab
770 )
771 .into());
772 }
773 let mut max_abs = 0.0f32;
774 let mut max_rel = 0.0f32;
775 let mut worst = 0usize;
776 let mut first_violation = None;
777 for (index, (&reference, &native)) in expected.logits.iter().zip(&actual.logits).enumerate() {
778 if !reference.is_finite() || !native.is_finite() {
779 return Err(format!("non-finite checkpoint logit at token {index}").into());
780 }
781 let absolute = (reference - native).abs();
782 let relative = absolute / reference.abs().max(1e-6);
783 if absolute > max_abs {
784 max_abs = absolute;
785 worst = index;
786 }
787 max_rel = max_rel.max(relative);
788 let allowed = gate.max_abs + gate.max_rel * reference.abs();
789 if absolute > allowed && first_violation.is_none() {
790 first_violation = Some((index, absolute, allowed));
791 }
792 }
793 let reference_argmax = stable_argmax(&expected.logits);
794 let native_argmax = stable_argmax(&actual.logits);
795 if let Some((index, absolute, allowed)) = first_violation {
796 return Err(format!(
797 "checkpoint parity failed at token {index}: abs={absolute} exceeds atol+rtol*abs(reference)={allowed}; observed max_abs={max_abs} at token {worst}, max_rel={max_rel}"
798 )
799 .into());
800 }
801 if gate.require_argmax && reference_argmax != native_argmax {
802 return Err(format!(
803 "checkpoint parity argmax mismatch: reference={reference_argmax} native={native_argmax}"
804 )
805 .into());
806 }
807 Ok(format!(
808 "status\tpassed\nreference_engine\t{}\nnative_engine\t{}\nnumeric_class\t{}\ntokens\t{}\nvocab\t{}\nmax_abs\t{max_abs}\nmax_rel\t{max_rel}\nreference_argmax\t{reference_argmax}\nnative_argmax\t{native_argmax}\n",
809 expected.engine,
810 actual.engine,
811 expected.numeric_class,
812 expected
813 .tokens
814 .iter()
815 .map(u32::to_string)
816 .collect::<Vec<_>>()
817 .join(","),
818 expected.vocab,
819 ))
820}
821
822fn stable_argmax(values: &[f32]) -> usize {
823 values
824 .iter()
825 .enumerate()
826 .max_by(|(left_index, left), (right_index, right)| {
827 left.total_cmp(right)
828 .then_with(|| right_index.cmp(left_index))
829 })
830 .map(|(index, _)| index)
831 .unwrap_or(0)
832}
833
834#[derive(Debug)]
835enum ReferenceVisionError {
836 Reference(memra_reference::ReferenceError),
837 Nondeterministic,
838}
839
840impl std::fmt::Display for ReferenceVisionError {
841 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
842 match self {
843 Self::Reference(error) => error.fmt(f),
844 Self::Nondeterministic => write!(
845 f,
846 "native vision reference fixture is not bit-deterministic"
847 ),
848 }
849 }
850}
851
852impl std::error::Error for ReferenceVisionError {}
853
854impl From<memra_reference::ReferenceError> for ReferenceVisionError {
855 fn from(value: memra_reference::ReferenceError) -> Self {
856 Self::Reference(value)
857 }
858}
859
860pub fn scaffold_model_pack(request: ScaffoldRequest) -> Result<(), Box<dyn std::error::Error>> {
861 validate_family_name(&request.family)?;
862 if request.out_dir.exists() && request.out_dir.read_dir()?.next().is_some() {
863 return Err(format!(
864 "refusing to scaffold into non-empty directory {}",
865 request.out_dir.display()
866 )
867 .into());
868 }
869 std::fs::create_dir_all(&request.out_dir)?;
870 write_atomic(
871 &request.out_dir.join("pack.toml"),
872 format!(
873 "family = {:?}\nconfig_layout = \"pending\"\nsupport = \"pending\"\n\n[checkpoint_parity]\nmax_abs = \"pending\"\nmax_rel = \"pending\"\nrequire_argmax = true\n",
874 request.family
875 )
876 .as_bytes(),
877 )?;
878 write_atomic(
879 &request.out_dir.join("aliases.txt"),
880 format!("{}\n", request.family).as_bytes(),
881 )?;
882 write_atomic(
883 &request.out_dir.join("config-normalization.txt"),
884 b"# source field\tcanonical field\ttransform\n",
885 )?;
886 write_atomic(
887 &request.out_dir.join("tensor-schema.tsv"),
888 b"semantic_id\tcheckpoint_pattern\tshape\townership\ttransform\tquant_layout\n",
889 )?;
890 write_atomic(
891 &request.out_dir.join("tokenizer-template.txt"),
892 b"tokenizer_source=pending\ntemplate=artifact-required\n",
893 )?;
894 write_atomic(
895 &request.out_dir.join("gates.txt"),
896 format_gates(&[
897 Gate::Config,
898 Gate::TokenizerTemplate,
899 Gate::TensorCensus,
900 Gate::TinyParity,
901 Gate::CheckpointParity,
902 Gate::RewriteParity,
903 Gate::Serve,
904 ])
905 .as_bytes(),
906 )?;
907 Ok(())
908}
909
910struct SourceData {
911 label: String,
912 revision: String,
913 dialect: CheckpointDialect,
914 config: ModelConfig,
915 config_bytes: Vec<u8>,
916 tensors: Vec<TensorCensusRecord>,
917 shards: Vec<String>,
918 tokenizer: Result<TokenizerEvidence, String>,
919}
920
921struct TokenizerEvidence {
922 source: TokenizerSource,
923 tokenizer_sha256: String,
924 template_sha256: String,
925 template_bytes: usize,
926}
927
928pub fn inspect_model(
929 request: InspectRequest,
930) -> Result<InspectSummary, Box<dyn std::error::Error>> {
931 let pack = model_packs::by_alias(&request.against)
932 .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
933 let source = load_source(&request.source)?;
934 let plan = pack.compile_plan(&source.config)?;
935 let output_head = if source
936 .tensors
937 .iter()
938 .any(|row| row.entry.name == "lm_head.weight" || row.entry.name == "output.weight")
939 {
940 OutputHead::Separate
941 } else {
942 OutputHead::TiedToEmbedding
943 };
944 let entries: Vec<_> = source.tensors.iter().map(|row| row.entry.clone()).collect();
945 std::fs::create_dir_all(&request.out_dir)?;
946 for stages in 2..=4 {
949 let path = request
950 .out_dir
951 .join(format!("placement-checkpoint-{stages}.tsv"));
952 match std::fs::remove_file(path) {
953 Ok(()) => {}
954 Err(error) if error.kind() == std::io::ErrorKind::NotFound => {}
955 Err(error) => return Err(error.into()),
956 }
957 }
958 let config_hash = hex_sha256(&source.config_bytes);
959 let census = format_census(&source.tensors);
960 let census_hash = hex_sha256(census.as_bytes());
961 let plan_text = format!("{plan:#?}\n");
962 let plan_hash = hex_sha256(plan_text.as_bytes());
963 let rewrites = memra_gguf::execution_manifest::execution_rewrites(&plan);
964 debug_assert!(
965 rewrites
966 .iter()
967 .all(|rewrite| rewrite.plan_sha256 == plan_hash)
968 );
969 let rewrite_manifest = format_execution_rewrites(&rewrites);
970 let rewrite_hash = hex_sha256(rewrite_manifest.as_bytes());
971 write_atomic(
972 &request.out_dir.join("tensor-census.tsv"),
973 census.as_bytes(),
974 )?;
975 write_atomic(
976 &request.out_dir.join("model-plan.txt"),
977 plan_text.as_bytes(),
978 )?;
979 write_atomic(
980 &request.out_dir.join("execution-rewrites.tsv"),
981 rewrite_manifest.as_bytes(),
982 )?;
983 let (binding, binding_error) = match pack.compile_tensor_contract(
984 &source.config,
985 &plan,
986 source.dialect,
987 ContractOptions { output_head },
988 ) {
989 Ok(contract) => match contract.bind(&entries) {
990 Ok(binding) => (Some(binding), None),
991 Err(error) => (None, Some(error.to_string())),
992 },
993 Err(error) => (None, Some(error.to_string())),
994 };
995 if let Some(binding) = binding.as_ref() {
996 write_checkpoint_placement_candidates(&request.out_dir, &plan, binding, &plan_hash)?;
997 }
998 let tokenizer_error = match &source.tokenizer {
999 Ok(evidence) if pack.tokenizer_sources.contains(&evidence.source) => None,
1000 Ok(evidence) => Some(format!(
1001 "model pack {} does not accept tokenizer source {:?}",
1002 pack.family, evidence.source
1003 )),
1004 Err(error) => Some(error.clone()),
1005 };
1006 if let Ok(evidence) = &source.tokenizer {
1007 write_atomic(
1008 &request.out_dir.join("tokenizer-contract.tsv"),
1009 format!(
1010 "status\tpassed\nsource\t{:?}\ntokenizer_sha256\t{}\ntemplate_sha256\t{}\ntemplate_bytes\t{}\n",
1011 evidence.source,
1012 evidence.tokenizer_sha256,
1013 evidence.template_sha256,
1014 evidence.template_bytes,
1015 )
1016 .as_bytes(),
1017 )?;
1018 }
1019 write_atomic(
1020 &request.out_dir.join("artifact.lock"),
1021 format_lock(
1022 pack,
1023 &source,
1024 &config_hash,
1025 &census_hash,
1026 &plan_hash,
1027 &rewrite_hash,
1028 if binding_error.is_some() {
1029 "failed"
1030 } else {
1031 "passed"
1032 },
1033 )
1034 .as_bytes(),
1035 )?;
1036 let error_path = request.out_dir.join("contract-error.txt");
1037 let tokenizer_error_path = request.out_dir.join("tokenizer-error.txt");
1038 let mut passed = vec![Gate::Config];
1039 let mut failed = Vec::new();
1040 if tokenizer_error.is_some() {
1041 failed.push(Gate::TokenizerTemplate);
1042 } else {
1043 passed.push(Gate::TokenizerTemplate);
1044 }
1045 if binding_error.is_some() {
1046 failed.push(Gate::TensorCensus);
1047 } else {
1048 passed.push(Gate::TensorCensus);
1049 }
1050 write_atomic(
1051 &request.out_dir.join("gates.txt"),
1052 format_gate_results_with_receipts(pack, &request.out_dir, &passed, &failed).as_bytes(),
1053 )?;
1054 if let Some(error) = binding_error.as_ref() {
1055 write_atomic(&error_path, format!("{error}\n").as_bytes())?;
1056 } else {
1057 match std::fs::remove_file(&error_path) {
1058 Ok(()) => {}
1059 Err(error) if error.kind() == std::io::ErrorKind::NotFound => {}
1060 Err(error) => return Err(error.into()),
1061 }
1062 }
1063 if let Some(error) = tokenizer_error.as_ref() {
1064 write_atomic(&tokenizer_error_path, format!("{error}\n").as_bytes())?;
1065 } else {
1066 match std::fs::remove_file(&tokenizer_error_path) {
1067 Ok(()) => {}
1068 Err(error) if error.kind() == std::io::ErrorKind::NotFound => {}
1069 Err(error) => return Err(error.into()),
1070 }
1071 }
1072 match (binding_error, tokenizer_error) {
1073 (Some(binding), Some(tokenizer)) => {
1074 return Err(
1075 format!("tensor contract: {binding}; tokenizer contract: {tokenizer}").into(),
1076 );
1077 }
1078 (Some(error), None) | (None, Some(error)) => return Err(error.into()),
1079 (None, None) => {}
1080 }
1081
1082 Ok(InspectSummary {
1083 family: pack.family,
1084 tensor_count: source.tensors.len(),
1085 out_dir: request.out_dir,
1086 })
1087}
1088
1089fn load_source(source: &str) -> Result<SourceData, Box<dyn std::error::Error>> {
1090 let path = Path::new(source);
1091 if path.exists() {
1092 return load_local(path);
1093 }
1094 let (repo, revision) = parse_pinned_hf_source(source)?;
1095 load_remote(repo, revision)
1096}
1097
1098fn load_config_only(source: &str) -> Result<ModelConfig, Box<dyn std::error::Error>> {
1099 let path = Path::new(source);
1100 if path.is_file() {
1101 return Ok(ModelConfig::from_gguf(&GgufFile::open(path)?));
1102 }
1103 if path.is_dir() {
1104 let bytes = std::fs::read(path.join("config.json"))?;
1105 return Ok(ModelConfig::from_hf(&HfConfig::parse(std::str::from_utf8(
1106 &bytes,
1107 )?)));
1108 }
1109 let (repo, revision) = parse_pinned_hf_source(source)?;
1110 let url = format!("https://huggingface.co/{repo}/resolve/{revision}/config.json");
1111 let config = http_text(&url)?.ok_or("pinned model has no config.json")?;
1112 Ok(ModelConfig::from_hf(&HfConfig::parse(&config)))
1113}
1114
1115fn load_local(path: &Path) -> Result<SourceData, Box<dyn std::error::Error>> {
1116 if path.is_file() {
1117 let gguf = GgufFile::open(path)?;
1118 let tokenizer = inspect_gguf_tokenizer(&gguf);
1119 let config = ModelConfig::from_gguf(&gguf);
1120 let tensors = census_from_gguf(&gguf).tensors;
1121 let config_bytes = format!("{config:#?}").into_bytes();
1122 return Ok(SourceData {
1123 label: path.display().to_string(),
1124 revision: "local".to_string(),
1125 dialect: CheckpointDialect::Gguf,
1126 config,
1127 config_bytes,
1128 tensors,
1129 shards: (0..gguf.n_shards())
1130 .map(|index| gguf.shard_path(index).display().to_string())
1131 .collect(),
1132 tokenizer,
1133 });
1134 }
1135
1136 if path.join("manifest.json").is_file() {
1137 let source = Hy3RepackSource::open(path)?;
1138 let config = source.try_config().map_err(std::io::Error::other)?;
1139 let census = source.tensor_census().map_err(std::io::Error::other)?;
1140 let tokenizer_dir = source.source_dir().unwrap_or(path);
1141 let tokenizer = inspect_hf_tokenizer_dir(tokenizer_dir);
1142 return Ok(SourceData {
1143 label: path.display().to_string(),
1144 revision: "local-repack".to_string(),
1145 dialect: census.dialect,
1146 config_bytes: format!("{config:#?}").into_bytes(),
1147 config,
1148 tensors: census.tensors,
1149 shards: vec!["manifest.json".to_string()],
1150 tokenizer,
1151 });
1152 }
1153
1154 let config_bytes = std::fs::read(path.join("config.json"))?;
1155 let config_text = std::str::from_utf8(&config_bytes)?;
1156 let config = ModelConfig::from_hf(&HfConfig::parse(config_text));
1157 let tokenizer = inspect_hf_tokenizer_dir(path);
1158 let model = StModel::open(path)?;
1159 let shards = local_shards(path)?;
1160 let revision = local_hf_revision(path, &shards).unwrap_or_else(|| "local".to_string());
1161 let headers = model
1162 .names()
1163 .map(|name| {
1164 let info = model.info(name).expect("StModel name must resolve");
1165 (name.clone(), info.clone())
1166 })
1167 .collect();
1168 Ok(SourceData {
1169 label: path.display().to_string(),
1170 revision,
1171 dialect: CheckpointDialect::HfSafetensors,
1172 config,
1173 config_bytes,
1174 tensors: census_from_safetensors_headers(&headers)?.tensors,
1175 shards,
1176 tokenizer,
1177 })
1178}
1179
1180fn load_remote(repo: &str, revision: &str) -> Result<SourceData, Box<dyn std::error::Error>> {
1181 let base = format!("https://huggingface.co/{repo}/resolve/{revision}");
1182 let config_bytes = http_text(&format!("{base}/config.json"))?
1183 .ok_or("pinned model has no config.json")?
1184 .into_bytes();
1185 let config = ModelConfig::from_hf(&HfConfig::parse(std::str::from_utf8(&config_bytes)?));
1186 let tokenizer = inspect_remote_hf_tokenizer(&base);
1187 let index = http_text(&format!("{base}/model.safetensors.index.json"))?;
1188 let shards: Vec<String> = if let Some(index) = index {
1189 let mut files: Vec<_> = parse_index_json(&index)?.into_values().collect();
1190 files.sort();
1191 files.dedup();
1192 files
1193 } else {
1194 vec!["model.safetensors".to_string()]
1195 };
1196 let mut headers = BTreeMap::new();
1197 for shard in &shards {
1198 validate_remote_filename(shard)?;
1199 let url = format!("{base}/{shard}");
1200 let prefix = http_range(&url, 0, 7)?;
1201 if prefix.len() != 8 {
1202 return Err(format!("{shard}: expected 8-byte safetensors prefix").into());
1203 }
1204 let header_len = u64::from_le_bytes(prefix.try_into().unwrap()) as usize;
1205 if header_len == 0 || header_len > MAX_TEXT_BYTES {
1206 return Err(format!("{shard}: invalid safetensors header length {header_len}").into());
1207 }
1208 let bytes = http_range(&url, 8, 7 + header_len)?;
1209 if bytes.len() != header_len {
1210 return Err(format!(
1211 "{shard}: range returned {} header bytes, expected {header_len}",
1212 bytes.len()
1213 )
1214 .into());
1215 }
1216 let parsed = parse_header(std::str::from_utf8(&bytes)?)?;
1217 for (name, info) in parsed {
1218 if headers.insert(name.clone(), info).is_some() {
1219 return Err(format!("tensor {name} occurs in multiple safetensors shards").into());
1220 }
1221 }
1222 }
1223 Ok(SourceData {
1224 label: repo.to_string(),
1225 revision: revision.to_string(),
1226 dialect: CheckpointDialect::HfSafetensors,
1227 config,
1228 config_bytes,
1229 tensors: census_from_safetensors_headers(&headers)?.tensors,
1230 shards,
1231 tokenizer,
1232 })
1233}
1234
1235fn inspect_gguf_tokenizer(gguf: &GgufFile) -> Result<TokenizerEvidence, String> {
1236 let model = gguf
1237 .metadata
1238 .get("tokenizer.ggml.model")
1239 .and_then(|value| value.as_str())
1240 .ok_or_else(|| "GGUF is missing tokenizer.ggml.model".to_string())?;
1241 let tokens = gguf
1242 .metadata
1243 .get("tokenizer.ggml.tokens")
1244 .and_then(|value| value.as_str_array())
1245 .ok_or_else(|| "GGUF is missing tokenizer.ggml.tokens".to_string())?;
1246 if tokens.is_empty() {
1247 return Err("GGUF tokenizer.ggml.tokens is empty".to_string());
1248 }
1249 let template = gguf
1250 .metadata
1251 .get("tokenizer.chat_template")
1252 .and_then(|value| value.as_str())
1253 .filter(|template| !template.trim().is_empty())
1254 .ok_or_else(|| "GGUF is missing tokenizer.chat_template".to_string())?;
1255 let mut hasher = Sha256::new();
1256 hasher.update(model.as_bytes());
1257 if let Some(pre) = gguf
1258 .metadata
1259 .get("tokenizer.ggml.pre")
1260 .and_then(|value| value.as_str())
1261 {
1262 hasher.update([0]);
1263 hasher.update(pre.as_bytes());
1264 }
1265 for token in tokens {
1266 hasher.update([0]);
1267 hasher.update(token.as_bytes());
1268 }
1269 Ok(TokenizerEvidence {
1270 source: TokenizerSource::GgufMetadata,
1271 tokenizer_sha256: hasher
1272 .finalize()
1273 .iter()
1274 .map(|byte| format!("{byte:02x}"))
1275 .collect(),
1276 template_sha256: hex_sha256(template.as_bytes()),
1277 template_bytes: template.len(),
1278 })
1279}
1280
1281fn inspect_hf_tokenizer_dir(path: &Path) -> Result<TokenizerEvidence, String> {
1282 let tokenizer_path = path.join("tokenizer.json");
1283 let tokenizer = std::fs::read(&tokenizer_path)
1284 .map_err(|error| format!("read {}: {error}", tokenizer_path.display()))?;
1285 let template = local_hf_template(path)?;
1286 Ok(TokenizerEvidence {
1287 source: TokenizerSource::TokenizerJson,
1288 tokenizer_sha256: hex_sha256(&tokenizer),
1289 template_sha256: hex_sha256(template.as_bytes()),
1290 template_bytes: template.len(),
1291 })
1292}
1293
1294fn local_hf_template(path: &Path) -> Result<String, String> {
1295 let config_path = path.join("tokenizer_config.json");
1296 if let Ok(config) = std::fs::read_to_string(&config_path)
1297 && let Some(template) = template_from_tokenizer_config(&config)
1298 {
1299 return Ok(template);
1300 }
1301 let template_path = path.join("chat_template.jinja");
1302 std::fs::read_to_string(&template_path)
1303 .map_err(|error| format!("read {}: {error}", template_path.display()))
1304 .and_then(nonempty_template)
1305}
1306
1307fn inspect_remote_hf_tokenizer(base: &str) -> Result<TokenizerEvidence, String> {
1308 let tokenizer = http_text(&format!("{base}/tokenizer.json"))
1309 .map_err(|error| error.to_string())?
1310 .ok_or_else(|| "pinned HF model has no tokenizer.json".to_string())?;
1311 let config =
1312 http_text(&format!("{base}/tokenizer_config.json")).map_err(|error| error.to_string())?;
1313 let template = config
1314 .as_deref()
1315 .and_then(template_from_tokenizer_config)
1316 .or_else(|| {
1317 http_text(&format!("{base}/chat_template.jinja"))
1318 .ok()
1319 .flatten()
1320 })
1321 .ok_or_else(|| {
1322 "pinned HF model has neither tokenizer_config chat_template nor chat_template.jinja"
1323 .to_string()
1324 })
1325 .and_then(nonempty_template)?;
1326 Ok(TokenizerEvidence {
1327 source: TokenizerSource::TokenizerJson,
1328 tokenizer_sha256: hex_sha256(tokenizer.as_bytes()),
1329 template_sha256: hex_sha256(template.as_bytes()),
1330 template_bytes: template.len(),
1331 })
1332}
1333
1334fn template_from_tokenizer_config(config: &str) -> Option<String> {
1335 let config = memra_gguf::config::JsonObj::parse(config);
1336 config
1337 .string("chat_template")
1338 .filter(|value| !value.trim().is_empty())
1339}
1340
1341fn nonempty_template(template: String) -> Result<String, String> {
1342 if template.trim().is_empty() {
1343 Err("chat template is empty".to_string())
1344 } else {
1345 Ok(template)
1346 }
1347}
1348
1349fn parse_pinned_hf_source(source: &str) -> Result<(&str, &str), Box<dyn std::error::Error>> {
1350 let (repo, revision) = source
1351 .rsplit_once('@')
1352 .ok_or("remote sources must be pinned as hf-id@40-char-sha")?;
1353 if repo.split('/').count() != 2
1354 || repo.split('/').any(|part| part.is_empty())
1355 || !repo
1356 .bytes()
1357 .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'/' | b'-' | b'_' | b'.'))
1358 || repo.contains("..")
1359 {
1360 return Err("HF model id must be namespace/repository".into());
1361 }
1362 if revision.len() != 40 || !revision.bytes().all(|byte| byte.is_ascii_hexdigit()) {
1363 return Err("HF revision must be a full 40-character commit SHA".into());
1364 }
1365 Ok((repo, revision))
1366}
1367
1368fn validate_family_name(family: &str) -> Result<(), Box<dyn std::error::Error>> {
1369 if family.is_empty()
1370 || !family
1371 .bytes()
1372 .all(|byte| byte.is_ascii_lowercase() || byte.is_ascii_digit() || byte == b'_')
1373 {
1374 return Err(
1375 "family must contain only lowercase ASCII letters, digits, and underscores".into(),
1376 );
1377 }
1378 Ok(())
1379}
1380
1381fn validate_remote_filename(name: &str) -> Result<(), Box<dyn std::error::Error>> {
1382 if name.is_empty()
1383 || name.starts_with('/')
1384 || name.split('/').any(|part| part.is_empty() || part == "..")
1385 || !name
1386 .bytes()
1387 .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'/' | b'-' | b'_' | b'.'))
1388 {
1389 return Err(format!("unsafe shard filename {name:?}").into());
1390 }
1391 Ok(())
1392}
1393
1394fn http_text(url: &str) -> Result<Option<String>, Box<dyn std::error::Error>> {
1395 let mut command = curl_command();
1396 command.args([
1397 "--silent",
1398 "--show-error",
1399 "--location",
1400 "--max-filesize",
1401 &MAX_TEXT_BYTES.to_string(),
1402 "--write-out",
1403 "\n%{http_code}",
1404 url,
1405 ]);
1406 let output = curl_output(command)?;
1407 if !output.status.success() {
1408 return Err(format!(
1409 "curl failed for {url}: {}",
1410 String::from_utf8_lossy(&output.stderr)
1411 )
1412 .into());
1413 }
1414 let split = output
1415 .stdout
1416 .iter()
1417 .rposition(|byte| *byte == b'\n')
1418 .ok_or("curl response omitted HTTP status")?;
1419 let status = std::str::from_utf8(&output.stdout[split + 1..])?.trim();
1420 match status {
1421 "200" => Ok(Some(String::from_utf8(output.stdout[..split].to_vec())?)),
1422 "404" => Ok(None),
1423 other => Err(format!("HTTP {other} for {url}").into()),
1424 }
1425}
1426
1427fn http_range(url: &str, start: usize, end: usize) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
1428 let mut command = curl_command();
1429 command.args([
1430 "--fail",
1431 "--silent",
1432 "--show-error",
1433 "--location",
1434 "--max-filesize",
1435 &MAX_TEXT_BYTES.to_string(),
1436 "--range",
1437 &format!("{start}-{end}"),
1438 url,
1439 ]);
1440 let output = curl_output(command)?;
1441 if !output.status.success() {
1442 return Err(format!(
1443 "range request failed for {url}: {}",
1444 String::from_utf8_lossy(&output.stderr)
1445 )
1446 .into());
1447 }
1448 Ok(output.stdout)
1449}
1450
1451fn curl_command() -> Command {
1452 Command::new("curl")
1453}
1454
1455fn curl_output(mut command: Command) -> std::io::Result<Output> {
1456 let token = std::env::var("HF_TOKEN").ok();
1457 if token.is_none() {
1458 return command.output();
1459 }
1460 command
1461 .args(["--header", "@-"])
1462 .stdin(Stdio::piped())
1463 .stdout(Stdio::piped())
1464 .stderr(Stdio::piped());
1465 let mut child = command.spawn()?;
1466 let mut stdin = child.stdin.take().expect("piped curl stdin");
1467 writeln!(stdin, "Authorization: Bearer {}", token.unwrap())?;
1468 drop(stdin);
1469 child.wait_with_output()
1470}
1471
1472fn local_shards(path: &Path) -> Result<Vec<String>, Box<dyn std::error::Error>> {
1473 let index = path.join("model.safetensors.index.json");
1474 if index.exists() {
1475 let mut shards: Vec<_> = parse_index_json(&std::fs::read_to_string(index)?)?
1476 .into_values()
1477 .collect();
1478 shards.sort();
1479 shards.dedup();
1480 Ok(shards)
1481 } else {
1482 Ok(vec!["model.safetensors".to_string()])
1483 }
1484}
1485
1486fn local_hf_revision(path: &Path, shards: &[String]) -> Option<String> {
1487 let metadata = path.join(".cache/huggingface/download");
1488 let mut files = Vec::with_capacity(shards.len() + 1);
1489 files.push("config.json");
1490 files.extend(shards.iter().map(String::as_str));
1491 let revisions: Option<Vec<_>> = files
1492 .into_iter()
1493 .map(|file| {
1494 let text = std::fs::read_to_string(metadata.join(format!("{file}.metadata"))).ok()?;
1495 let revision = text.lines().next()?;
1496 (revision.len() == 40 && revision.bytes().all(|byte| byte.is_ascii_hexdigit()))
1497 .then(|| revision.to_ascii_lowercase())
1498 })
1499 .collect();
1500 let revisions = revisions?;
1501 let first = revisions.first()?;
1502 revisions
1503 .iter()
1504 .all(|revision| revision == first)
1505 .then(|| first.clone())
1506}
1507
1508fn format_census(rows: &[TensorCensusRecord]) -> String {
1509 let mut output =
1510 String::from("semantic_name\tphysical_name\tdtype\tshape\tstorage\tphysical_bytes\n");
1511 for row in rows {
1512 writeln!(
1513 output,
1514 "{}\t{}\t{}\t{:?}\t{:?}\t{}",
1515 row.entry.name,
1516 row.physical_name,
1517 row.dtype,
1518 row.entry.shape,
1519 row.entry.storage,
1520 row.entry.physical_bytes,
1521 )
1522 .unwrap();
1523 }
1524 output
1525}
1526
1527fn placement_first_stage_tensor(id: &TensorId) -> bool {
1528 match id {
1529 TensorId::TokenEmbedding | TensorId::RopeFactors | TensorId::Vision { .. } => true,
1530 TensorId::QuantAux { tensor, .. } => placement_first_stage_tensor(tensor),
1531 _ => false,
1532 }
1533}
1534
1535fn write_checkpoint_placement_candidates(
1536 out_dir: &Path,
1537 plan: &memra_gguf::model_plan::ModelPlan,
1538 binding: &BoundTensorContract,
1539 plan_hash: &str,
1540) -> Result<(), Box<dyn std::error::Error>> {
1541 let mut layers = vec![LayerPlacementCost::default(); plan.layers.len()];
1542 let mut first_fixed = 0u64;
1543 let mut last_fixed = 0u64;
1544 for (id, tensor) in &binding.tensors {
1545 match tensor.owner {
1546 TensorOwner::Layer(layer) if (layer as usize) < layers.len() => {
1547 let cost = &mut layers[layer as usize];
1548 cost.weight_bytes = cost
1549 .weight_bytes
1550 .checked_add(tensor.physical_bytes)
1551 .ok_or("layer checkpoint byte total overflows u64")?;
1552 }
1553 TensorOwner::Layer(_) => {
1556 last_fixed = last_fixed
1557 .checked_add(tensor.physical_bytes)
1558 .ok_or("head-stage checkpoint byte total overflows u64")?;
1559 }
1560 TensorOwner::Vision(_) => {
1561 first_fixed = first_fixed
1562 .checked_add(tensor.physical_bytes)
1563 .ok_or("first-stage checkpoint byte total overflows u64")?;
1564 }
1565 TensorOwner::Global if placement_first_stage_tensor(id) => {
1566 first_fixed = first_fixed
1567 .checked_add(tensor.physical_bytes)
1568 .ok_or("first-stage checkpoint byte total overflows u64")?;
1569 }
1570 TensorOwner::Global | TensorOwner::Mtp(_) => {
1571 last_fixed = last_fixed
1572 .checked_add(tensor.physical_bytes)
1573 .ok_or("head-stage checkpoint byte total overflows u64")?;
1574 }
1575 }
1576 }
1577
1578 for stages in 2..=4.min(layers.len()) {
1579 let devices: Vec<usize> = (0..stages).collect();
1580 let mut fixed = vec![0u64; stages];
1581 fixed[0] = first_fixed;
1582 fixed[stages - 1] = fixed[stages - 1]
1583 .checked_add(last_fixed)
1584 .ok_or("head-stage checkpoint byte total overflows u64")?;
1585 let candidate = plan_contiguous_stages(PlacementRequest {
1586 layers: &layers,
1587 fixed_stage_bytes: &fixed,
1588 context_tokens: 0,
1589 devices: &devices,
1590 legal_boundaries: &plan.partition_boundaries,
1591 });
1592 let mut output = String::new();
1593 writeln!(output, "basis\tcheckpoint_physical_bytes")?;
1594 writeln!(output, "plan_sha256\t{plan_hash}")?;
1595 writeln!(output, "context_tokens\t0")?;
1596 writeln!(
1597 output,
1598 "warning\tnot exact HBM: loader expansions, repacks, mirrors, KV and workspaces require runtime planning"
1599 )?;
1600 match candidate {
1601 Ok(candidate) => {
1602 let cuts = candidate
1603 .stages
1604 .iter()
1605 .take(candidate.stages.len() - 1)
1606 .map(|stage| stage.layers.end.to_string())
1607 .collect::<Vec<_>>()
1608 .join(",");
1609 writeln!(output, "status\tpassed")?;
1610 writeln!(output, "MEMRA_PP_STAGES\t{stages}")?;
1611 writeln!(
1612 output,
1613 "MEMRA_PP_DEVICES\t{}",
1614 devices
1615 .iter()
1616 .map(usize::to_string)
1617 .collect::<Vec<_>>()
1618 .join(",")
1619 )?;
1620 writeln!(output, "MEMRA_PP_SPLITS\t{cuts}")?;
1621 writeln!(output, "max_stage_bytes\t{}", candidate.max_stage_bytes)?;
1622 writeln!(
1623 output,
1624 "stage\tdevice\tlayers\tweight_bytes\tfixed_bytes\ttotal_bytes"
1625 )?;
1626 for (stage, placement) in candidate.stages.iter().enumerate() {
1627 writeln!(
1628 output,
1629 "{stage}\t{}\t{}..{}\t{}\t{}\t{}",
1630 placement.device,
1631 placement.layers.start,
1632 placement.layers.end,
1633 placement.cost.weight_bytes,
1634 placement.cost.fixed_bytes,
1635 placement.cost.total_bytes,
1636 )?;
1637 }
1638 }
1639 Err(error) => {
1640 writeln!(output, "status\tfailed")?;
1641 writeln!(output, "error\t{error}")?;
1642 }
1643 }
1644 write_atomic(
1645 &out_dir.join(format!("placement-checkpoint-{stages}.tsv")),
1646 output.as_bytes(),
1647 )?;
1648 }
1649 Ok(())
1650}
1651
1652fn format_execution_rewrites(
1653 rewrites: &[memra_gguf::execution_manifest::ExecutionRewrite],
1654) -> String {
1655 let mut output = String::from(
1656 "rewrite\tsurface\timplementation\tplan_sha256\teligible\tblockers\toperations\treceipt\n",
1657 );
1658 for rewrite in rewrites {
1659 let blockers = rewrite
1660 .blockers
1661 .iter()
1662 .map(|operation| format!("{operation:?}"))
1663 .collect::<Vec<_>>()
1664 .join(",");
1665 let mut unique_operations = Vec::new();
1666 for operation in &rewrite.canonical_operations {
1667 if !unique_operations.contains(operation) {
1668 unique_operations.push(*operation);
1669 }
1670 }
1671 let operations = unique_operations
1672 .iter()
1673 .map(|operation| format!("{operation:?}"))
1674 .collect::<Vec<_>>()
1675 .join(",");
1676 writeln!(
1677 output,
1678 "{}\t{}\t{}\t{}\t{}\t{}\t{}\tpending",
1679 rewrite.id,
1680 rewrite.surface.as_str(),
1681 rewrite.implementation,
1682 rewrite.plan_sha256,
1683 rewrite.eligible(),
1684 blockers,
1685 operations,
1686 )
1687 .unwrap();
1688 }
1689 output
1690}
1691
1692fn format_lock(
1693 pack: &ModelPack,
1694 source: &SourceData,
1695 config: &str,
1696 census: &str,
1697 plan: &str,
1698 rewrites: &str,
1699 binding: &str,
1700) -> String {
1701 let mut output = String::from("format_version=2\n");
1702 writeln!(output, "source={}", lock_value(&source.label)).unwrap();
1703 writeln!(output, "revision={}", lock_value(&source.revision)).unwrap();
1704 writeln!(output, "family={}", pack.family).unwrap();
1705 match pack.support {
1706 Some(support) => writeln!(output, "support={support:?}").unwrap(),
1707 None => writeln!(output, "support=unsupported").unwrap(),
1708 }
1709 if let Some(gate) = pack.checkpoint_parity {
1710 writeln!(output, "checkpoint_atol={}", gate.max_abs).unwrap();
1711 writeln!(output, "checkpoint_rtol={}", gate.max_rel).unwrap();
1712 writeln!(output, "checkpoint_require_argmax={}", gate.require_argmax).unwrap();
1713 }
1714 writeln!(output, "config_sha256={config}").unwrap();
1715 writeln!(output, "census_sha256={census}").unwrap();
1716 writeln!(output, "plan_sha256={plan}").unwrap();
1717 writeln!(output, "rewrite_manifest_sha256={rewrites}").unwrap();
1718 writeln!(output, "binding={binding}").unwrap();
1719 match &source.tokenizer {
1720 Ok(evidence) if pack.tokenizer_sources.contains(&evidence.source) => {
1721 writeln!(output, "tokenizer=passed").unwrap();
1722 writeln!(output, "tokenizer_source={:?}", evidence.source).unwrap();
1723 writeln!(output, "tokenizer_sha256={}", evidence.tokenizer_sha256).unwrap();
1724 writeln!(output, "template_sha256={}", evidence.template_sha256).unwrap();
1725 }
1726 Ok(_) | Err(_) => writeln!(output, "tokenizer=failed").unwrap(),
1727 }
1728 writeln!(output, "tensor_count={}", source.tensors.len()).unwrap();
1729 for shard in &source.shards {
1730 writeln!(output, "shard={}", lock_value(shard)).unwrap();
1731 }
1732 output
1733}
1734
1735fn parse_header(
1736 json: &str,
1737) -> Result<std::collections::HashMap<String, StInfo>, Box<dyn std::error::Error>> {
1738 parse_header_json_checked(json).map_err(Into::into)
1739}
1740
1741fn parse_index_json(
1742 json: &str,
1743) -> Result<std::collections::HashMap<String, String>, Box<dyn std::error::Error>> {
1744 parse_index_weight_map_json_checked(json).map_err(Into::into)
1745}
1746
1747fn lock_value(value: &str) -> String {
1748 value
1749 .replace('\\', "\\\\")
1750 .replace('\n', "\\n")
1751 .replace('\r', "\\r")
1752}
1753
1754fn format_gates(gates: &[Gate]) -> String {
1755 format_gate_results(gates, &[], &[])
1756}
1757
1758fn format_gate_results(gates: &[Gate], passed: &[Gate], failed: &[Gate]) -> String {
1759 let mut output = String::new();
1760 for gate in gates {
1761 let status = if passed.contains(gate) {
1762 "passed"
1763 } else if failed.contains(gate) {
1764 "failed"
1765 } else {
1766 "pending"
1767 };
1768 writeln!(output, "{gate:?}={status}").unwrap();
1769 }
1770 output
1771}
1772
1773fn all_eligible_rewrites_have_receipts(out_dir: &Path) -> bool {
1774 let Ok(manifest) = std::fs::read_to_string(out_dir.join("execution-rewrites.tsv")) else {
1775 return false;
1776 };
1777 let Ok(index_text) = std::fs::read_to_string(out_dir.join("rewrite-receipts.tsv")) else {
1778 return false;
1779 };
1780 let mut index = BTreeMap::new();
1781 for line in index_text.lines().skip(1) {
1782 let columns: Vec<_> = line.split('\t').collect();
1783 if columns.len() != 4 || columns[3] != "passed" {
1784 return false;
1785 }
1786 index.insert(columns[0], (columns[1], columns[2]));
1787 }
1788 let mut eligible = 0usize;
1789 for line in manifest.lines().skip(1) {
1790 let columns: Vec<_> = line.split('\t').collect();
1791 if columns.len() != 8 {
1792 return false;
1793 }
1794 if columns[4] != "true" {
1795 continue;
1796 }
1797 eligible += 1;
1798 let Some(&(plan, receipt_hash)) = index.get(columns[0]) else {
1799 return false;
1800 };
1801 if plan != columns[3] {
1802 return false;
1803 }
1804 let Ok(receipt) = std::fs::read(
1805 out_dir
1806 .join("rewrite-receipts")
1807 .join(format!("{}.tsv", columns[0])),
1808 ) else {
1809 return false;
1810 };
1811 if hex_sha256(&receipt) != receipt_hash {
1812 return false;
1813 }
1814 }
1815 eligible > 0
1816}
1817
1818fn format_gate_results_with_receipts(
1819 pack: &ModelPack,
1820 out_dir: &Path,
1821 passed: &[Gate],
1822 failed: &[Gate],
1823) -> String {
1824 let mut passed = passed.to_vec();
1825 let artifact_lock = std::fs::read(out_dir.join("artifact.lock")).ok();
1826 let lock_hash = artifact_lock.as_ref().map(|bytes| hex_sha256(bytes));
1827 if let Some(lock) = artifact_lock
1828 .as_deref()
1829 .and_then(|bytes| std::str::from_utf8(bytes).ok())
1830 .filter(|lock| {
1831 lock.lines().any(|line| line == "format_version=2")
1832 && lock
1833 .lines()
1834 .any(|line| line == format!("family={}", pack.family))
1835 })
1836 {
1837 for (gate, evidence) in [
1838 (Gate::Config, None),
1839 (Gate::TokenizerTemplate, Some("tokenizer=passed")),
1840 (Gate::TensorCensus, Some("binding=passed")),
1841 ] {
1842 if evidence.is_none_or(|line| lock.lines().any(|candidate| candidate == line))
1843 && !passed.contains(&gate)
1844 && !failed.contains(&gate)
1845 {
1846 passed.push(gate);
1847 }
1848 }
1849 }
1850 let receipt_passes = |name: &str, family_bound: bool, lock_bound: bool| {
1851 let Ok(receipt) = std::fs::read_to_string(out_dir.join(name)) else {
1852 return false;
1853 };
1854 if !receipt.lines().any(|line| line == "status\tpassed") {
1855 return false;
1856 }
1857 if family_bound
1858 && !receipt
1859 .lines()
1860 .any(|line| line == format!("family\t{}", pack.family))
1861 {
1862 return false;
1863 }
1864 if lock_bound
1865 && !lock_hash.as_ref().is_some_and(|hash| {
1866 receipt
1867 .lines()
1868 .any(|line| line == format!("artifact_lock_sha256\t{hash}"))
1869 })
1870 {
1871 return false;
1872 }
1873 true
1874 };
1875 for (gate, name, family_bound, lock_bound) in [
1876 (Gate::TinyParity, "tiny-gate.tsv", true, false),
1877 (Gate::CheckpointParity, "checkpoint-parity.tsv", false, true),
1878 (Gate::Serve, "serve-gate.tsv", true, true),
1879 ] {
1880 if receipt_passes(name, family_bound, lock_bound)
1881 && !passed.contains(&gate)
1882 && !failed.contains(&gate)
1883 {
1884 passed.push(gate);
1885 }
1886 }
1887 if all_eligible_rewrites_have_receipts(out_dir)
1888 && !passed.contains(&Gate::RewriteParity)
1889 && !failed.contains(&Gate::RewriteParity)
1890 {
1891 passed.push(Gate::RewriteParity);
1892 }
1893 format_gate_results(pack.gates, &passed, failed)
1894}
1895
1896fn format_tiny_fixture(
1897 plan: &memra_gguf::model_plan::ModelPlan,
1898 fixture: &memra_reference::ReferenceFixture,
1899) -> String {
1900 let mut output = format!("tokens={:?}\nplan={plan:#?}\n", fixture.token_ids);
1901 for (id, tensor) in &fixture.weights {
1902 let mut bytes = Vec::with_capacity(tensor.data.len() * 4);
1903 for value in &tensor.data {
1904 bytes.extend_from_slice(&value.to_bits().to_le_bytes());
1905 }
1906 writeln!(
1907 output,
1908 "tensor={id:?}\tshape={:?}\tsha256={}",
1909 tensor.shape,
1910 hex_sha256(&bytes)
1911 )
1912 .unwrap();
1913 }
1914 if let Some(vision) = fixture.vision.as_ref() {
1915 let mut bytes = Vec::with_capacity(vision.patches.data.len() * 4);
1916 for value in &vision.patches.data {
1917 bytes.extend_from_slice(&value.to_bits().to_le_bytes());
1918 }
1919 writeln!(
1920 output,
1921 "vision_patches={:?}\tsha256={}\tpositions={:?}\toutput_tokens={}",
1922 vision.patches.shape,
1923 hex_sha256(&bytes),
1924 vision.positions,
1925 vision.output_tokens,
1926 )
1927 .unwrap();
1928 }
1929 if let Some(token_ids) = fixture.multimodal_token_ids.as_ref() {
1930 writeln!(output, "multimodal_tokens={token_ids:?}").unwrap();
1931 }
1932 output
1933}
1934
1935fn format_reference_oracle(output: &memra_reference::ReferenceOutput) -> String {
1936 let mut text = String::from("stream\tposition\ttoken\tlogit_f32_bits\n");
1937 append_oracle_rows(
1938 &mut text,
1939 "main",
1940 &output.logits,
1941 output.tokens,
1942 output.vocab,
1943 );
1944 for mtp in &output.mtp {
1945 append_oracle_rows(
1946 &mut text,
1947 &format!("mtp:{}", mtp.depth),
1948 &mtp.logits,
1949 output.tokens,
1950 output.vocab,
1951 );
1952 }
1953 if let Some(draft) = output.draft.as_ref() {
1954 append_oracle_rows(
1955 &mut text,
1956 "dspark",
1957 &draft.logits,
1958 draft.block_size,
1959 output.vocab,
1960 );
1961 for (position, (&token, &confidence)) in draft
1962 .output_ids
1963 .iter()
1964 .skip(1)
1965 .zip(&draft.confidence)
1966 .enumerate()
1967 {
1968 writeln!(
1969 text,
1970 "dspark-confidence\t{position}\t{token}\t{:08x}",
1971 confidence.to_bits()
1972 )
1973 .unwrap();
1974 }
1975 }
1976 text
1977}
1978
1979fn append_oracle_rows(
1980 text: &mut String,
1981 stream: &str,
1982 logits: &[f32],
1983 tokens: usize,
1984 vocab: usize,
1985) {
1986 for position in 0..tokens {
1987 for token in 0..vocab {
1988 writeln!(
1989 text,
1990 "{stream}\t{position}\t{token}\t{:08x}",
1991 logits[position * vocab + token].to_bits()
1992 )
1993 .unwrap();
1994 }
1995 }
1996}
1997
1998fn format_reference_vision_oracle(output: &memra_reference::ReferenceVisionOutput) -> String {
1999 let mut text = String::from("stream\tposition\tchannel\tf32_bits\n");
2000 for (stream, values, rows, width) in [
2001 (
2002 "vision-encoder",
2003 output.encoder_hidden.as_slice(),
2004 output.patch_count,
2005 output.hidden_size,
2006 ),
2007 (
2008 "vision-pooled",
2009 output.pooled_hidden.as_slice(),
2010 output.output_tokens,
2011 output.hidden_size,
2012 ),
2013 (
2014 "vision-projected",
2015 output.projected_hidden.as_slice(),
2016 output.output_tokens,
2017 output.projection_size,
2018 ),
2019 ] {
2020 for position in 0..rows {
2021 for channel in 0..width {
2022 writeln!(
2023 text,
2024 "{stream}\t{position}\t{channel}\t{:08x}",
2025 values[position * width + channel].to_bits()
2026 )
2027 .unwrap();
2028 }
2029 }
2030 }
2031 text
2032}
2033
2034fn hex_sha256(bytes: &[u8]) -> String {
2035 let digest = Sha256::digest(bytes);
2036 digest.iter().map(|byte| format!("{byte:02x}")).collect()
2037}
2038
2039fn write_atomic(path: &Path, bytes: &[u8]) -> std::io::Result<()> {
2040 let temporary = path.with_extension(format!("tmp-{}", std::process::id()));
2041 std::fs::write(&temporary, bytes)?;
2042 std::fs::rename(temporary, path)
2043}
2044
2045#[cfg(test)]
2046mod tests {
2047 use super::*;
2048
2049 #[test]
2050 fn local_glm_fixture_generates_deterministic_onboarding_artifacts() {
2051 let root = std::env::temp_dir().join(format!("memra-cli-inspect-{}", std::process::id()));
2052 let model = root.join("model.gguf");
2053 let output = root.join("out");
2054 std::fs::create_dir_all(&root).unwrap();
2055 memra_gguf::micro_gguf::write_glm_dsa_micro(&model, 0x434c_4901).unwrap();
2056 let verified = verify_model(VerifyRequest {
2057 stage: VerifyStage::Config,
2058 source: model.display().to_string(),
2059 against: "glm_dsa".to_string(),
2060 out_dir: None,
2061 oracle: None,
2062 native_runner: None,
2063 })
2064 .unwrap();
2065 assert_eq!(verified.stage, VerifyStage::Config);
2066 let first = inspect_model(InspectRequest {
2067 source: model.display().to_string(),
2068 against: "glm_dsa".to_string(),
2069 out_dir: output.clone(),
2070 })
2071 .unwrap();
2072 assert_eq!(first.family, "glm_dsa");
2073 assert!(first.tensor_count > 0);
2074 let lock = std::fs::read(output.join("artifact.lock")).unwrap();
2075 std::fs::write(output.join("placement-checkpoint-3.tsv"), "stale\n").unwrap();
2076 std::fs::write(output.join("placement-checkpoint-4.tsv"), "stale\n").unwrap();
2077 inspect_model(InspectRequest {
2078 source: model.display().to_string(),
2079 against: "glm_dsa".to_string(),
2080 out_dir: output.clone(),
2081 })
2082 .unwrap();
2083 assert_eq!(std::fs::read(output.join("artifact.lock")).unwrap(), lock);
2084 for artifact in [
2085 "artifact.lock",
2086 "tensor-census.tsv",
2087 "model-plan.txt",
2088 "execution-rewrites.tsv",
2089 "placement-checkpoint-2.tsv",
2090 "gates.txt",
2091 ] {
2092 assert!(output.join(artifact).is_file(), "missing {artifact}");
2093 }
2094 let placement = std::fs::read_to_string(output.join("placement-checkpoint-2.tsv")).unwrap();
2095 assert!(placement.contains("basis\tcheckpoint_physical_bytes"));
2096 assert!(placement.contains("warning\tnot exact HBM"));
2097 assert!(placement.contains("MEMRA_PP_STAGES\t2"));
2098 assert!(!output.join("placement-checkpoint-3.tsv").exists());
2099 assert!(!output.join("placement-checkpoint-4.tsv").exists());
2100 std::fs::remove_dir_all(root).unwrap();
2101 }
2102
2103 #[test]
2104 fn pinned_source_and_wrapper_normalization_fail_closed() {
2105 assert!(parse_pinned_hf_source("org/model@main").is_err());
2106 let sha = "a".repeat(40);
2107 assert_eq!(
2108 parse_pinned_hf_source(&format!("org/model@{sha}")).unwrap(),
2109 ("org/model", sha.as_str())
2110 );
2111 assert_eq!(
2112 canonical_hf_name("model.language_model.layers.1.self_attn.q_proj.weight"),
2113 "model.layers.1.self_attn.q_proj.weight"
2114 );
2115 }
2116
2117 #[test]
2118 fn local_repack_inspect_routes_metadata_census_into_placement() {
2119 use memra_gguf::tensor_contract::TensorMatch;
2120
2121 let root =
2122 std::env::temp_dir().join(format!("memra-cli-repack-inspect-{}", std::process::id()));
2123 let output = root.join("out");
2124 std::fs::create_dir_all(&root).unwrap();
2125 let config_json = r#"{"model_type":"qwen3","num_hidden_layers":2,"hidden_size":8,
2126 "num_attention_heads":2,"num_key_value_heads":1,"head_dim":4,
2127 "intermediate_size":16,"vocab_size":32,"max_position_embeddings":32,
2128 "rms_norm_eps":0.000001}"#;
2129 std::fs::write(root.join("config.json"), config_json).unwrap();
2130 std::fs::write(root.join("tokenizer.json"), "{}").unwrap();
2131 std::fs::write(
2132 root.join("tokenizer_config.json"),
2133 r#"{"chat_template":"{{ messages }}"}"#,
2134 )
2135 .unwrap();
2136 let config = ModelConfig::from_hf(&HfConfig::parse(config_json));
2137 let pack = model_packs::by_alias("qwen3").unwrap();
2138 let plan = pack.compile_plan(&config).unwrap();
2139 let contract = pack
2140 .compile_tensor_contract(
2141 &config,
2142 &plan,
2143 CheckpointDialect::Gguf,
2144 ContractOptions {
2145 output_head: OutputHead::Separate,
2146 },
2147 )
2148 .unwrap();
2149 let mut tensors = BTreeMap::<String, Vec<u64>>::new();
2150 for requirement in contract.requirements {
2151 if !requirement.required {
2152 continue;
2153 }
2154 let names: Vec<_> = match requirement.match_mode {
2155 TensorMatch::OneOf => requirement.names.into_iter().take(1).collect(),
2156 TensorMatch::All => requirement.names,
2157 };
2158 for name in names {
2159 tensors.insert(name, requirement.shape.clone());
2160 }
2161 }
2162 let mut blob = Vec::new();
2163 let mut fields = Vec::new();
2164 for (name, shape) in tensors {
2165 let bytes = shape.iter().product::<u64>() as usize * 4;
2166 let offset = blob.len();
2167 blob.resize(offset + bytes, 0);
2168 fields.push(format!(
2169 "{name:?}:{{\"file\":\"weights.bin\",\"offset\":{offset},\"qtype\":\"F32\",\"ne\":{:?},\"bytes\":{bytes}}}",
2170 shape,
2171 ));
2172 }
2173 std::fs::write(root.join("weights.bin"), blob).unwrap();
2174 std::fs::write(
2175 root.join("manifest.json"),
2176 format!(
2177 "{{\"format\":\"memra-repack-v1\",\"tensors\":{{{}}}}}",
2178 fields.join(",")
2179 ),
2180 )
2181 .unwrap();
2182
2183 let summary = inspect_model(InspectRequest {
2184 source: root.display().to_string(),
2185 against: "qwen3".to_string(),
2186 out_dir: output.clone(),
2187 })
2188 .unwrap();
2189 assert_eq!(summary.family, "qwen3");
2190 assert!(summary.tensor_count > 0);
2191 assert!(output.join("placement-checkpoint-2.tsv").is_file());
2192 std::fs::remove_dir_all(root).ok();
2193 }
2194
2195 #[test]
2196 fn scaffold_is_deterministic_and_refuses_non_empty_targets() {
2197 let root = std::env::temp_dir().join(format!("memra-cli-scaffold-{}", std::process::id()));
2198 scaffold_model_pack(ScaffoldRequest {
2199 family: "new_family".to_string(),
2200 out_dir: root.clone(),
2201 })
2202 .unwrap();
2203 for artifact in [
2204 "pack.toml",
2205 "aliases.txt",
2206 "config-normalization.txt",
2207 "tensor-schema.tsv",
2208 "tokenizer-template.txt",
2209 "gates.txt",
2210 ] {
2211 assert!(root.join(artifact).is_file(), "missing {artifact}");
2212 }
2213 assert!(
2214 scaffold_model_pack(ScaffoldRequest {
2215 family: "new_family".to_string(),
2216 out_dir: root.clone(),
2217 })
2218 .is_err()
2219 );
2220 assert!(validate_family_name("Bad-Family").is_err());
2221 std::fs::remove_dir_all(root).unwrap();
2222 }
2223
2224 #[test]
2225 fn unimplemented_verify_stages_refuse_without_fallback() {
2226 {
2227 let stage = VerifyStage::Serve;
2228 let error = verify_model(VerifyRequest {
2229 stage,
2230 source: "unused".to_string(),
2231 against: "qwen3".to_string(),
2232 out_dir: None,
2233 oracle: None,
2234 native_runner: None,
2235 })
2236 .err()
2237 .unwrap()
2238 .to_string();
2239 assert!(error.contains("no fallback is allowed"));
2240 }
2241 }
2242
2243 #[test]
2244 fn supported_packs_write_deterministic_native_oracles() {
2245 let root = std::env::temp_dir().join(format!("memra-cli-tiny-{}", std::process::id()));
2246 let request = || VerifyRequest {
2247 stage: VerifyStage::Tiny,
2248 source: "unused".to_string(),
2249 against: "qwen3".to_string(),
2250 out_dir: Some(root.clone()),
2251 oracle: None,
2252 native_runner: None,
2253 };
2254 verify_model(request()).unwrap();
2255 let fixture = std::fs::read(root.join("tiny-fixture.txt")).unwrap();
2256 let oracle = std::fs::read(root.join("reference-oracle.tsv")).unwrap();
2257 verify_model(request()).unwrap();
2258 assert_eq!(
2259 std::fs::read(root.join("tiny-fixture.txt")).unwrap(),
2260 fixture
2261 );
2262 assert_eq!(
2263 std::fs::read(root.join("reference-oracle.tsv")).unwrap(),
2264 oracle
2265 );
2266 for pack in model_packs::PACKS {
2267 if pack.family == "qwen3" {
2268 continue;
2269 }
2270 let result = verify_model(VerifyRequest {
2271 stage: VerifyStage::Tiny,
2272 source: "unused".to_string(),
2273 against: pack.family.to_string(),
2274 out_dir: Some(root.join(pack.family)),
2275 oracle: None,
2276 native_runner: None,
2277 });
2278 if pack.support.is_some() {
2279 result.unwrap();
2280 assert!(
2281 root.join(pack.family)
2282 .join("reference-oracle.tsv")
2283 .is_file()
2284 );
2285 if pack.family.starts_with("gemma4") {
2286 assert!(
2287 root.join(pack.family)
2288 .join("reference-vision-oracle.tsv")
2289 .is_file()
2290 );
2291 assert!(
2292 root.join(pack.family)
2293 .join("reference-multimodal-oracle.tsv")
2294 .is_file()
2295 );
2296 }
2297 } else {
2298 assert!(result.is_err());
2299 }
2300 }
2301 std::fs::remove_dir_all(root).unwrap();
2302 }
2303
2304 #[test]
2305 fn checkpoint_oracle_bundle_is_pinned_and_parity_is_fail_closed() {
2306 let root = std::env::temp_dir().join(format!(
2307 "memra-cli-checkpoint-oracle-{}",
2308 std::process::id()
2309 ));
2310 std::fs::create_dir_all(&root).unwrap();
2311 let sha = "0123456789abcdef0123456789abcdef01234567";
2312 write_hf_oracle_bundle(&format!("org/model@{sha}"), &root).unwrap();
2313 let request = std::fs::read_to_string(root.join("oracle-request.tsv")).unwrap();
2314 let script = std::fs::read_to_string(root.join("capture-hf-oracle.py")).unwrap();
2315 assert!(request.contains(&format!("revision\t{sha}")));
2316 assert!(script.contains(&format!("REVISION = \"{sha}\"")));
2317 assert!(script.contains("trust_remote_code=False"));
2318 assert!(script.contains("dtype=torch.float32"));
2319 assert!(script.contains("source-weights-float32-accumulation"));
2320
2321 let oracle = |engine: &str, values: &[f32]| {
2322 let mut text = format!(
2323 "format\tmemra-checkpoint-oracle-v1\nengine\t{engine}\nnumeric_class\tsource-weights-float32-accumulation\ntokens\t1,2,3,4\nvocab\t{}\n",
2324 values.len()
2325 );
2326 for (index, value) in values.iter().enumerate() {
2327 writeln!(text, "logit\t{index}\t{:08x}", value.to_bits()).unwrap();
2328 }
2329 parse_checkpoint_oracle(&text).unwrap()
2330 };
2331 let reference = oracle("hf-transformers", &[0.0, 1.0, -1.0]);
2332 let native = oracle("memra-native", &[0.0, 1.001, -1.001]);
2333 let gate = model_packs::CheckpointParityGate {
2334 max_abs: 0.01,
2335 max_rel: 2.0,
2336 require_argmax: true,
2337 };
2338 assert!(compare_checkpoint_oracles(&reference, &native, gate).is_ok());
2339 let failing = oracle("memra-native", &[2.0, 1.0, -1.0]);
2340 assert!(compare_checkpoint_oracles(&reference, &failing, gate).is_err());
2341 std::fs::remove_dir_all(root).unwrap();
2342 }
2343
2344 #[test]
2345 fn rewrite_verifier_binds_manifest_plan_and_exact_streams() {
2346 let root =
2347 std::env::temp_dir().join(format!("memra-cli-rewrite-receipt-{}", std::process::id()));
2348 std::fs::create_dir_all(&root).unwrap();
2349 let config = ModelConfig::from_hf(&HfConfig::parse(
2350 r#"{"model_type":"qwen3","num_hidden_layers":2,"hidden_size":64,
2351 "num_attention_heads":2,"num_key_value_heads":1,"head_dim":32,
2352 "intermediate_size":128,"vocab_size":16,"max_position_embeddings":128}"#,
2353 ));
2354 let plan = memra_gguf::model_plan::ModelPlan::compile(&config).unwrap();
2355 let rewrites = memra_gguf::execution_manifest::execution_rewrites(&plan);
2356 let rewrite = rewrites
2357 .iter()
2358 .find(|rewrite| {
2359 rewrite.surface == memra_gguf::execution_manifest::RewriteSurface::DecodeBatch
2360 })
2361 .unwrap();
2362 let artifact_lock = b"format_version=2\nfamily=qwen3\n";
2363 std::fs::write(root.join("artifact.lock"), artifact_lock).unwrap();
2364 std::fs::write(
2365 root.join("execution-rewrites.tsv"),
2366 format_execution_rewrites(&rewrites),
2367 )
2368 .unwrap();
2369 let receipt = rewrite
2370 .verify_logits(
2371 &"00".repeat(32),
2372 &[0.0, 1.0, -1.0],
2373 &[0.0, 1.0, -1.0],
2374 memra_gguf::execution_manifest::RewriteParityPolicy {
2375 max_abs: 0.0,
2376 max_rel: 0.0,
2377 require_argmax: true,
2378 },
2379 )
2380 .unwrap()
2381 .bind_artifact_lock(artifact_lock)
2382 .to_tsv();
2383 let receipt_path = root.join("receipt.tsv");
2384 std::fs::write(&receipt_path, &receipt).unwrap();
2385 verify_rewrite_receipt(
2386 model_packs::by_alias("qwen3").unwrap(),
2387 &receipt_path,
2388 &root,
2389 )
2390 .unwrap();
2391 assert!(
2392 std::fs::read_to_string(root.join("rewrite-receipts.tsv"))
2393 .unwrap()
2394 .contains("decode-batch.v1")
2395 );
2396
2397 let wrong = receipt.replace(&rewrite.plan_sha256, &"11".repeat(32));
2398 std::fs::write(&receipt_path, wrong).unwrap();
2399 assert!(
2400 verify_rewrite_receipt(
2401 model_packs::by_alias("qwen3").unwrap(),
2402 &receipt_path,
2403 &root,
2404 )
2405 .is_err()
2406 );
2407 std::fs::remove_dir_all(root).unwrap();
2408 }
2409
2410 #[cfg(unix)]
2411 #[test]
2412 fn native_serve_gate_launches_readiness_and_completion_on_real_http() {
2413 use std::os::unix::fs::PermissionsExt;
2414
2415 let root =
2416 std::env::temp_dir().join(format!("memra-cli-serve-gate-{}", std::process::id()));
2417 let model = root.join("model");
2418 std::fs::create_dir_all(&model).unwrap();
2419 let artifact_lock = format!(
2420 "source={}\nbinding=passed\ntokenizer=passed\n",
2421 lock_value(model.to_str().unwrap())
2422 );
2423 std::fs::write(root.join("artifact.lock"), &artifact_lock).unwrap();
2424 std::fs::write(
2425 root.join("checkpoint-parity.tsv"),
2426 format!(
2427 "status\tpassed\nartifact_lock_sha256\t{}\n",
2428 hex_sha256(artifact_lock.as_bytes())
2429 ),
2430 )
2431 .unwrap();
2432 let runner = root.join("fake-memra-server.py");
2433 std::fs::write(
2434 &runner,
2435 r#"#!/usr/bin/env python3
2436import json, os
2437from http.server import BaseHTTPRequestHandler, HTTPServer
2438host, port = os.environ["MEMRA_ADDR"].rsplit(":", 1)
2439class Handler(BaseHTTPRequestHandler):
2440 def log_message(self, *args): pass
2441 def do_GET(self):
2442 self.send_response(200 if self.path == "/readyz" else 404)
2443 self.end_headers()
2444 self.wfile.write(b"ready")
2445 def do_POST(self):
2446 length = int(self.headers.get("content-length", "0"))
2447 self.rfile.read(length)
2448 body = json.dumps({"choices":[{"text":"ok"}]}).encode()
2449 self.send_response(200)
2450 self.send_header("content-type", "application/json")
2451 self.send_header("content-length", str(len(body)))
2452 self.end_headers()
2453 self.wfile.write(body)
2454HTTPServer((host, int(port)), Handler).serve_forever()
2455"#,
2456 )
2457 .unwrap();
2458 let mut permissions = std::fs::metadata(&runner).unwrap().permissions();
2459 permissions.set_mode(0o755);
2460 std::fs::set_permissions(&runner, permissions).unwrap();
2461 verify_native_serve(
2462 model_packs::by_alias("qwen3").unwrap(),
2463 model.to_str().unwrap(),
2464 &root,
2465 &runner,
2466 )
2467 .unwrap();
2468 assert!(root.join("serve-response.json").is_file());
2469 assert!(
2470 std::fs::read_to_string(root.join("gates.txt"))
2471 .unwrap()
2472 .contains("Serve=passed")
2473 );
2474 std::fs::remove_dir_all(root).unwrap();
2475 }
2476}