brandonmusic commited on
Commit
9a22f03
·
verified ·
1 Parent(s): c14142d

Shakeout fixes: CUDA-free platform probe, 16-way parallel verify, sharded forward w/ replica parity, transformers==5.12.1 pin, torchvision removal

Browse files
r7_encoder/inventory.py CHANGED
@@ -248,11 +248,22 @@ def verify_checkpoint_inventory(
248
  raw_shards = payload.get("shards")
249
  if not isinstance(raw_shards, dict):
250
  raise ValueError("checkpoint inventory lacks shard map")
251
- for shard_name, record in sorted(raw_shards.items()):
 
252
  if not isinstance(record, dict) or sha256_file(root / shard_name) != record.get(
253
  "file_sha256"
254
  ):
255
  raise ValueError(f"checkpoint shard changed after inventory: {shard_name}")
 
 
 
 
 
 
 
 
 
 
256
  auxiliary = payload.get("auxiliary_files_sha256")
257
  if not isinstance(auxiliary, dict) or not auxiliary:
258
  raise ValueError("checkpoint inventory lacks auxiliary/tokenizer assets")
@@ -396,7 +407,13 @@ def _collect_execution_platform(
396
  "torch_version": str(torch.__version__),
397
  "torch_git_version": str(getattr(torch.version, "git_version", "UNKNOWN")),
398
  "torch_cuda_build": str(torch.version.cuda),
399
- "torch_cudnn_build": str(torch.backends.cudnn.version()),
 
 
 
 
 
 
400
  "device": _nvidia_device_record(device),
401
  "torch_numerical_binaries_sha256": torch_binaries,
402
  "dynamic_dependency_closure_sha256": _dynamic_library_closure(dynamic_roots),
 
248
  raw_shards = payload.get("shards")
249
  if not isinstance(raw_shards, dict):
250
  raise ValueError("checkpoint inventory lacks shard map")
251
+ def _check_shard(item):
252
+ shard_name, record = item
253
  if not isinstance(record, dict) or sha256_file(root / shard_name) != record.get(
254
  "file_sha256"
255
  ):
256
  raise ValueError(f"checkpoint shard changed after inventory: {shard_name}")
257
+
258
+ # Hash shards in parallel; identical failure semantics (any mismatch
259
+ # raises), deterministic because each check is independent and the full
260
+ # set must pass. Turns a ~25-minute single-thread startup verify into a
261
+ # few minutes on every launch and resume.
262
+ from concurrent.futures import ThreadPoolExecutor
263
+
264
+ with ThreadPoolExecutor(max_workers=16) as _pool:
265
+ for _ in _pool.map(_check_shard, sorted(raw_shards.items())):
266
+ pass
267
  auxiliary = payload.get("auxiliary_files_sha256")
268
  if not isinstance(auxiliary, dict) or not auxiliary:
269
  raise ValueError("checkpoint inventory lacks auxiliary/tokenizer assets")
 
407
  "torch_version": str(torch.__version__),
408
  "torch_git_version": str(getattr(torch.version, "git_version", "UNKNOWN")),
409
  "torch_cuda_build": str(torch.version.cuda),
410
+ # cuDNN build parsed from static build info: torch.backends.cudnn
411
+ # .version() initializes CUDA, which would trip the runtime's
412
+ # CUDA-purity gate 26 minutes later at walk startup.
413
+ "torch_cudnn_build": (
414
+ (re.search(r"CuDNN[^\n]*?([\d.]+)", torch.__config__.show())
415
+ or [None, "UNKNOWN"])[1]
416
+ ),
417
  "device": _nvidia_device_record(device),
418
  "torch_numerical_binaries_sha256": torch_binaries,
419
  "dynamic_dependency_closure_sha256": _dynamic_library_closure(dynamic_roots),
r7_encoder/transformers_runtime.py CHANGED
@@ -220,6 +220,12 @@ class TransformersSequentialRuntime(GLM52Runtime):
220
  )
221
 
222
  self.device = torch.device(config.device)
 
 
 
 
 
 
223
  if self.device.type != "cuda":
224
  raise ValueError(
225
  "the owner-run GLM reference runtime requires one CUDA device"
@@ -506,7 +512,8 @@ class TransformersSequentialRuntime(GLM52Runtime):
506
  "auxiliary": "prev_topk_indices-int32",
507
  }
508
 
509
- def _context(self, hidden, metadata: Mapping[str, object]):
 
510
  import torch
511
 
512
  tokens = int(metadata["tokens"])
@@ -517,21 +524,21 @@ class TransformersSequentialRuntime(GLM52Runtime):
517
  ):
518
  raise ValueError("state metadata is not the pinned one-prompt DSA schema")
519
  x = (
520
- torch.as_tensor(hidden, device=self.device)
521
  .reshape(1, tokens, HIDDEN_SIZE)
522
  .to(torch.bfloat16)
523
  )
524
- position_ids = torch.arange(tokens, device=self.device).unsqueeze(0)
525
  minimum = torch.finfo(x.dtype).min
526
  causal = torch.full(
527
- (tokens, tokens), minimum, device=self.device, dtype=x.dtype
528
  ).triu(diagonal=1)
529
  attention_mask = causal.unsqueeze(0).unsqueeze(0)
530
  position_embeddings = self.rotary(x, position_ids)
531
  previous = metadata.get("prev_topk_indices")
532
  if previous is not None:
533
  previous = torch.as_tensor(
534
- previous, device=self.device, dtype=torch.int32
535
  ).unsqueeze(0)
536
  return x, attention_mask, position_ids, position_embeddings, previous
537
 
@@ -562,12 +569,12 @@ class TransformersSequentialRuntime(GLM52Runtime):
562
  gate_up = torch.empty(
563
  (NUM_EXPERTS, 2 * INTERMEDIATE_SIZE, HIDDEN_SIZE),
564
  dtype=torch.bfloat16,
565
- device=self.device,
566
  )
567
  down = torch.empty(
568
  (NUM_EXPERTS, HIDDEN_SIZE, INTERMEDIATE_SIZE),
569
  dtype=torch.bfloat16,
570
- device=self.device,
571
  )
572
  for expert in range(NUM_EXPERTS):
573
  gate_up[expert, :INTERMEDIATE_SIZE] = installed[expert][
@@ -594,8 +601,8 @@ class TransformersSequentialRuntime(GLM52Runtime):
594
  module.eval()
595
  return module
596
 
597
- def _advance(self, module, hidden, metadata):
598
- context = self._context(hidden, metadata)
599
  x, mask, positions, rotary, previous = context
600
  with __import__("torch").inference_mode():
601
  output, topk = module(
@@ -1360,22 +1367,25 @@ class TransformersSequentialRuntime(GLM52Runtime):
1360
  }
1361
  carrier_audit = sha256_bytes(canonical_json_bytes(layer_records))
1362
  first_shard_id = input_values[0].shard_id
 
 
 
 
 
 
 
 
 
1363
  try:
1364
- for shard in input_values:
1365
- if shard.shard_id in completed_shard_ids:
1366
- continue
1367
  reader = SafeTensorReader(shard.hidden_path)
1368
  hidden = read_torch_tensor(reader, "hidden")
1369
  previous = read_torch_tensor(reader, "prev_topk_indices")
1370
  metadata = read_json(shard.metadata_path)
1371
  metadata["prev_topk_indices"] = previous
1372
- if shard.shard_id == first_shard_id:
1373
- output, topk, repeat_audit = self._advance_repeat_oracle(
1374
- module, hidden, metadata
1375
- )
1376
- else:
1377
- output, topk = self._advance(module, hidden, metadata)
1378
- repeat_audit = None
1379
  successor = dict(metadata)
1380
  successor.pop("prev_topk_indices", None)
1381
  successor["producer"] = f"round7-installed-layer-{layer:03d}"
@@ -1383,18 +1393,112 @@ class TransformersSequentialRuntime(GLM52Runtime):
1383
  successor["carrier_decode_audit_sha256"] = carrier_audit
1384
  if repeat_audit is not None:
1385
  successor["official_repeat_audit"] = repeat_audit
1386
- # Yield immediately: the walk seals this prompt in PARTIAL.json
1387
- # before the runtime starts the next expensive prompt.
1388
- yield self._write_state(
1389
- output_partial=output_partial,
1390
- layer_input=layer + 1,
1391
- shard_id=shard.shard_id,
1392
- hidden=output,
1393
- previous_topk=topk,
1394
- metadata=successor,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1395
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1396
  finally:
1397
  del module
 
 
 
1398
  self._installed.pop(layer, None)
1399
  torch.cuda.empty_cache()
1400
 
 
220
  )
221
 
222
  self.device = torch.device(config.device)
223
+ # Optional device pool for the sharded successor forward. Pool of one
224
+ # (the default) is byte-identical to the original sequential flow.
225
+ _pool = tuple(getattr(config, "devices", ()) or ()) or (config.device,)
226
+ if _pool[0] != config.device:
227
+ raise ValueError("forward device pool must start with the primary device")
228
+ self.forward_devices = tuple(torch.device(item) for item in _pool)
229
  if self.device.type != "cuda":
230
  raise ValueError(
231
  "the owner-run GLM reference runtime requires one CUDA device"
 
512
  "auxiliary": "prev_topk_indices-int32",
513
  }
514
 
515
+ def _context(self, hidden, metadata: Mapping[str, object], device=None):
516
+ device = self.device if device is None else device
517
  import torch
518
 
519
  tokens = int(metadata["tokens"])
 
524
  ):
525
  raise ValueError("state metadata is not the pinned one-prompt DSA schema")
526
  x = (
527
+ torch.as_tensor(hidden, device=device)
528
  .reshape(1, tokens, HIDDEN_SIZE)
529
  .to(torch.bfloat16)
530
  )
531
+ position_ids = torch.arange(tokens, device=device).unsqueeze(0)
532
  minimum = torch.finfo(x.dtype).min
533
  causal = torch.full(
534
+ (tokens, tokens), minimum, device=device, dtype=x.dtype
535
  ).triu(diagonal=1)
536
  attention_mask = causal.unsqueeze(0).unsqueeze(0)
537
  position_embeddings = self.rotary(x, position_ids)
538
  previous = metadata.get("prev_topk_indices")
539
  if previous is not None:
540
  previous = torch.as_tensor(
541
+ previous, device=device, dtype=torch.int32
542
  ).unsqueeze(0)
543
  return x, attention_mask, position_ids, position_embeddings, previous
544
 
 
569
  gate_up = torch.empty(
570
  (NUM_EXPERTS, 2 * INTERMEDIATE_SIZE, HIDDEN_SIZE),
571
  dtype=torch.bfloat16,
572
+ device=device,
573
  )
574
  down = torch.empty(
575
  (NUM_EXPERTS, HIDDEN_SIZE, INTERMEDIATE_SIZE),
576
  dtype=torch.bfloat16,
577
+ device=device,
578
  )
579
  for expert in range(NUM_EXPERTS):
580
  gate_up[expert, :INTERMEDIATE_SIZE] = installed[expert][
 
601
  module.eval()
602
  return module
603
 
604
+ def _advance(self, module, hidden, metadata, device=None):
605
+ context = self._context(hidden, metadata, device=device)
606
  x, mask, positions, rotary, previous = context
607
  with __import__("torch").inference_mode():
608
  output, topk = module(
 
1367
  }
1368
  carrier_audit = sha256_bytes(canonical_json_bytes(layer_records))
1369
  first_shard_id = input_values[0].shard_id
1370
+ devices = getattr(self, "forward_devices", None) or (
1371
+ getattr(self, "device", None),
1372
+ )
1373
+ pending = [
1374
+ shard
1375
+ for shard in input_values
1376
+ if shard.shard_id not in completed_shard_ids
1377
+ ]
1378
+ replicas: list = []
1379
  try:
1380
+ def _load_shard(shard):
 
 
1381
  reader = SafeTensorReader(shard.hidden_path)
1382
  hidden = read_torch_tensor(reader, "hidden")
1383
  previous = read_torch_tensor(reader, "prev_topk_indices")
1384
  metadata = read_json(shard.metadata_path)
1385
  metadata["prev_topk_indices"] = previous
1386
+ return hidden, metadata
1387
+
1388
+ def _successor(shard, metadata, repeat_audit, parity_audit):
 
 
 
 
1389
  successor = dict(metadata)
1390
  successor.pop("prev_topk_indices", None)
1391
  successor["producer"] = f"round7-installed-layer-{layer:03d}"
 
1393
  successor["carrier_decode_audit_sha256"] = carrier_audit
1394
  if repeat_audit is not None:
1395
  successor["official_repeat_audit"] = repeat_audit
1396
+ if parity_audit is not None:
1397
+ successor["replica_parity_audit"] = parity_audit
1398
+ return successor
1399
+
1400
+ sequential = (
1401
+ len(devices) <= 1
1402
+ or len(pending) <= 1
1403
+ # Mid-layer resume: the oracle prompt is already sealed, so
1404
+ # the parity check has no reference. Sequential handles it.
1405
+ or pending[0].shard_id != first_shard_id
1406
+ )
1407
+ if sequential:
1408
+ # Original sequential flow, byte-identical.
1409
+ for shard in pending:
1410
+ hidden, metadata = _load_shard(shard)
1411
+ if shard.shard_id == first_shard_id:
1412
+ output, topk, repeat_audit = self._advance_repeat_oracle(
1413
+ module, hidden, metadata
1414
+ )
1415
+ else:
1416
+ output, topk = self._advance(module, hidden, metadata)
1417
+ repeat_audit = None
1418
+ # Yield immediately: the walk seals this prompt in
1419
+ # PARTIAL.json before the next expensive prompt starts.
1420
+ yield self._write_state(
1421
+ output_partial=output_partial,
1422
+ layer_input=layer + 1,
1423
+ shard_id=shard.shard_id,
1424
+ hidden=output,
1425
+ previous_topk=topk,
1426
+ metadata=_successor(shard, metadata, repeat_audit, None),
1427
+ )
1428
+ return
1429
+
1430
+ # Sharded successor forward across the device pool. Compute fans
1431
+ # out to worker replicas; every state write and yield stays on
1432
+ # THIS thread in canonical shard order, so PARTIAL.json sealing,
1433
+ # resume semantics, and state hashing are unchanged.
1434
+ import copy
1435
+ from concurrent.futures import ThreadPoolExecutor
1436
+
1437
+ first_shard = pending[0]
1438
+ first_hidden, first_metadata = _load_shard(first_shard)
1439
+ output, topk, repeat_audit = self._advance_repeat_oracle(
1440
+ module, first_hidden, first_metadata
1441
+ )
1442
+ # Replicate only after the primary oracle passes, and prove every
1443
+ # replica reproduces the primary bytes before trusting it with
1444
+ # calibration state.
1445
+ replica_parity = {
1446
+ "schema": "r7-replica-parity-v1",
1447
+ "devices": [str(item) for item in devices],
1448
+ }
1449
+ modules = [module]
1450
+ for extra in devices[1:]:
1451
+ replica = copy.deepcopy(module).to(extra)
1452
+ r_out, r_topk = self._advance(
1453
+ replica, first_hidden, first_metadata, device=extra
1454
  )
1455
+ if not torch.equal(r_out, output) or not torch.equal(
1456
+ r_topk, topk
1457
+ ):
1458
+ raise RuntimeError(
1459
+ f"replica on {extra} diverged from the primary "
1460
+ "successor forward; refusing sharded execution"
1461
+ )
1462
+ replicas.append(replica)
1463
+ modules.append(replica)
1464
+ replica_parity["passed"] = True
1465
+ yield self._write_state(
1466
+ output_partial=output_partial,
1467
+ layer_input=layer + 1,
1468
+ shard_id=first_shard.shard_id,
1469
+ hidden=output,
1470
+ previous_topk=topk,
1471
+ metadata=_successor(
1472
+ first_shard, first_metadata, repeat_audit, replica_parity
1473
+ ),
1474
+ )
1475
+
1476
+ def _compute(index_shard):
1477
+ index, shard = index_shard
1478
+ worker = index % len(modules)
1479
+ hidden, metadata = _load_shard(shard)
1480
+ out, tk = self._advance(
1481
+ modules[worker], hidden, metadata, device=devices[worker]
1482
+ )
1483
+ return shard, metadata, out, tk
1484
+
1485
+ with ThreadPoolExecutor(max_workers=len(modules)) as pool:
1486
+ for shard, metadata, out, tk in pool.map(
1487
+ _compute, enumerate(pending[1:])
1488
+ ):
1489
+ yield self._write_state(
1490
+ output_partial=output_partial,
1491
+ layer_input=layer + 1,
1492
+ shard_id=shard.shard_id,
1493
+ hidden=out,
1494
+ previous_topk=tk,
1495
+ metadata=_successor(shard, metadata, None, None),
1496
+ )
1497
  finally:
1498
  del module
1499
+ for replica in replicas:
1500
+ del replica
1501
+ replicas.clear()
1502
  self._installed.pop(layer, None)
1503
  torch.cuda.empty_cache()
1504
 
run_scripts/setup_box.sh CHANGED
@@ -5,7 +5,13 @@
5
  # plus the encoder oracles validate the rebuilt extension on behavior.
6
  set -e
7
  python3 -m pip install --break-system-packages -q torch==2.12.1+cu132 --index-url https://download.pytorch.org/whl/cu132
8
- python3 -m pip install --break-system-packages -q transformers safetensors pytest ninja setuptools wheel "huggingface_hub[hf_transfer]"
 
 
 
 
 
 
9
  tar xzf exl3_v0043_src.tgz -C exl3src
10
  cd exl3src && TORCH_CUDA_ARCH_LIST=10.0 MAX_JOBS=64 python3 -m pip install --break-system-packages --no-deps --no-build-isolation .
11
  python3 -c "import torch, exllamav3_ext; print('ext OK on torch', torch.__version__)"
 
5
  # plus the encoder oracles validate the rebuilt extension on behavior.
6
  set -e
7
  python3 -m pip install --break-system-packages -q torch==2.12.1+cu132 --index-url https://download.pytorch.org/whl/cu132
8
+ # transformers PINNED: the runtime is authored against 5.12.1
9
+ # (GlmMoeDsaNaiveMoe was refactored away in later versions).
10
+ python3 -m pip install --break-system-packages -q "transformers==5.12.1" safetensors pytest ninja setuptools wheel "huggingface_hub[hf_transfer]"
11
+ # remove image-bundled torchvision/torchaudio: built against older torch,
12
+ # their ABI-mismatched op registration explodes inside transformers imports
13
+ python3 -m pip uninstall -y --break-system-packages torchvision torchaudio 2>/dev/null || true
14
+ python3 -c "import importlib.util; assert importlib.util.find_spec('torchvision') is None, 'torchvision still present'"
15
  tar xzf exl3_v0043_src.tgz -C exl3src
16
  cd exl3src && TORCH_CUDA_ARCH_LIST=10.0 MAX_JOBS=64 python3 -m pip install --break-system-packages --no-deps --no-build-isolation .
17
  python3 -c "import torch, exllamav3_ext; print('ext OK on torch', torch.__version__)"