verifiers 0.3.2.dev101__py3-none-any.whl → 0.3.2.dev102__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
verifiers/v1/graph.py CHANGED
@@ -673,8 +673,41 @@ def _attribute_mm(
673
673
  )
674
674
 
675
675
 
676
+ def _replace_placeholder_routing_row(
677
+ trace: Trace, prefix_node_ids: list[int], arr: np.ndarray, off: int
678
+ ) -> None:
679
+ """Replace the prefix's placeholder routing row with the one this turn's prefill forwarded."""
680
+ if not 1 <= off <= arr.shape[0]:
681
+ return
682
+ # Only assistant (`sampled`) nodes are affected: the model forward isn't run on the final
683
+ # generated token for such turns, meaning its routing decisions are fundamentally unavailable.
684
+ # But, because routing needs one row per token, that row instead receives an inaccurate
685
+ # placeholder, attempt to fix up below.
686
+ node_with_placeholder = None
687
+ for nid in reversed(prefix_node_ids):
688
+ if trace.nodes[nid].token_ids:
689
+ node_with_placeholder = trace.nodes[nid]
690
+ break
691
+ if node_with_placeholder is None or not node_with_placeholder.sampled:
692
+ return
693
+ node_rows = node_with_placeholder.routed_experts
694
+ if (
695
+ node_rows is None
696
+ or node_rows.shape[0] == 0
697
+ or node_rows.shape[1:] != arr.shape[1:]
698
+ ):
699
+ return
700
+ # Row `i` of this turn's array is sequence position `start + i`, so the prefix's final position
701
+ # is `arr[off - 1]`. Concatenating widens the node when this turn serialized `uint16`, where an
702
+ # in-place write would truncate.
703
+ node_with_placeholder.routed_experts = np.concatenate(
704
+ [node_rows[:-1], arr[off - 1 : off]], axis=0
705
+ )
706
+
707
+
676
708
  def _attribute_routed_experts(
677
709
  trace: Trace,
710
+ prefix_node_ids: list[int],
678
711
  new_node_ids: list[int],
679
712
  path_len: int,
680
713
  payload: Any,
@@ -683,7 +716,8 @@ def _attribute_routed_experts(
683
716
  payload's array covers the turn's prompt+completion from `payload["start"]` (0 = from token
684
717
  0); the nodes created this turn tile sequence positions `[path_len:]` in creation order, so
685
718
  we hand each node `arr[off : off+len(node.token_ids)]` and advance. Reused-prefix nodes keep
686
- the routing attributed when they were first created. A node whose slice falls outside the
719
+ the routing attributed when they were first created, except for the one position this turn
720
+ corrects (see `_replace_placeholder_routing_row`). A node whose slice falls outside the
687
721
  array (a `start` past `path_len`, e.g. an unexpected prefix-cache delta) is left unset — the
688
722
  branch then reports no routing rather than misaligning."""
689
723
  if payload is None:
@@ -693,6 +727,7 @@ def _attribute_routed_experts(
693
727
  payload["shape"]
694
728
  )
695
729
  off = path_len - int(payload.get("start", 0) or 0)
730
+ _replace_placeholder_routing_row(trace, prefix_node_ids, arr, off)
696
731
  needed = off + sum(len(trace.nodes[nid].token_ids) for nid in new_node_ids)
697
732
  for nid in new_node_ids:
698
733
  n = len(trace.nodes[nid].token_ids)
@@ -701,8 +736,8 @@ def _attribute_routed_experts(
701
736
  # Own only this node's rows; a view would retain the turn's full-context array.
702
737
  trace.nodes[nid].routed_experts = arr[off:end].copy()
703
738
  elif n and arr.shape[0] and 0 <= off and end == needed == arr.shape[0] + 1:
704
- # The engine omits the turn's final position because no forward pass follows it.
705
- # Pad only the final node's suffix instead of copying the full-context array.
739
+ # No forward pass follows the turn's final position, so it gets a placeholder: a
740
+ # copy of the previous row, appended to this node's slice of the array.
706
741
  trace.nodes[nid].routed_experts = np.concatenate(
707
742
  [arr[off:], arr[-1:]], axis=0
708
743
  )
@@ -813,7 +848,7 @@ def _commit_turn(turn: PendingTurn, response: Response) -> int:
813
848
  parent = prefix[-1] if prefix else None
814
849
  # cursor: in prompt_ids, the end of the previous *new* message's tokens
815
850
  cursor: int | None = None
816
- # Track new nodes separately so routed-expert attribution does not need this full path.
851
+ # Track new nodes separately so routed-expert attribution needs only node ids, not this path.
817
852
  new_node_ids: list[int] = []
818
853
  # Materialize the reused message path only for multimodal cursor attribution.
819
854
  mm_path: list[tuple[int, Message]] | None = None
@@ -874,8 +909,9 @@ def _commit_turn(turn: PendingTurn, response: Response) -> int:
874
909
 
875
910
  # Attribute this turn's expert-routing array onto the nodes created this turn (new input
876
911
  # nodes in creation order, then the assistant node), each getting the routing for its tokens.
912
+ # The prefix goes in too, so the position the previous turn could only pad can be corrected.
877
913
  _attribute_routed_experts(
878
- trace, new_node_ids, path_len, tokens.routed_experts if tokens else None
914
+ trace, prefix, new_node_ids, path_len, tokens.routed_experts if tokens else None
879
915
  )
880
916
 
881
917
  # Sampling masks are completion-aligned, so only the sampled node carries them.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: verifiers
3
- Version: 0.3.2.dev101
3
+ Version: 0.3.2.dev102
4
4
  Summary: Verifiers: Environments for LLM Reinforcement Learning
5
5
  Project-URL: Homepage, https://github.com/primeintellect-ai/verifiers
6
6
  Project-URL: Documentation, https://github.com/primeintellect-ai/verifiers
@@ -5,7 +5,7 @@ verifiers/v1/agent.py,sha256=rFjoAn9vpRXoyIZTzMgIuGb6HczTSuOenaB-U-x09to,32489
5
5
  verifiers/v1/env.py,sha256=Hon7gcepciMYgki_jN4-l4XCcKRZRYuYm7c17nfeiFE,18520
6
6
  verifiers/v1/episode.py,sha256=Fft0R2W6INAVeJhoE9b8h7L_KQSz7XuxP4FT_XhcsUY,5741
7
7
  verifiers/v1/errors.py,sha256=uQySmCUrjDYFkBIii1vBFPiEcPFPQZ9EGpas_6HvcQI,5279
8
- verifiers/v1/graph.py,sha256=yJufZ9vMCBUshC9w19SpKyf6IJqQ7NHcv8iSdP0w7BU,39009
8
+ verifiers/v1/graph.py,sha256=b3Z3lCnsALnAvY82pDnjhODFYakkeLV_hXgGOvbryrQ,40737
9
9
  verifiers/v1/harness.py,sha256=sXEjVdrS4A2SO35C_uEebBVeUt8VL7dui7IneAp2MRs,14124
10
10
  verifiers/v1/judge.py,sha256=uqn-djkK2_7Q3kOjkDo6ipOvV_HOvuLa9y6AoDjRux8,9618
11
11
  verifiers/v1/rollout.py,sha256=KjfxxIQIqk2X3ZbWUHUn-1nWl04JdYwdVj7ELJtKgbw,24168
@@ -190,8 +190,8 @@ verifiers/v1/utils/prime.py,sha256=UTYRjp9cbjNb6CVmBHda-1wWZAIIfxNOmTyNuT7_wL4,9
190
190
  verifiers/v1/utils/retries.py,sha256=Y2ZgrAjn-qNkRKZP_RVNL_7EK0iaRcZeCa404lpGYi4,5417
191
191
  verifiers/v1/utils/score.py,sha256=493yJVMw8teCu9JxapxMFPFzI0hNUqdo0Y2nGW4kckk,6200
192
192
  verifiers/v1/utils/version.py,sha256=-obEo_-l9-D8FLef4hYxncOe-uJpxrM1g2Hig_37Sgs,1607
193
- verifiers-0.3.2.dev101.dist-info/METADATA,sha256=t7FmSXg76hCUpvPZ4X17hP-MTCSpo_IIYUqT7nKksjk,4238
194
- verifiers-0.3.2.dev101.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
195
- verifiers-0.3.2.dev101.dist-info/entry_points.txt,sha256=iugElcdWPKbQM7uFF0lZ8iUpHsNr17-BwEAAjJWxV3U,259
196
- verifiers-0.3.2.dev101.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
197
- verifiers-0.3.2.dev101.dist-info/RECORD,,
193
+ verifiers-0.3.2.dev102.dist-info/METADATA,sha256=bgoqfsVCE7mh66RzwnfvlX0Jcxbi05QJO_JMjrSPUpI,4238
194
+ verifiers-0.3.2.dev102.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
195
+ verifiers-0.3.2.dev102.dist-info/entry_points.txt,sha256=iugElcdWPKbQM7uFF0lZ8iUpHsNr17-BwEAAjJWxV3U,259
196
+ verifiers-0.3.2.dev102.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
197
+ verifiers-0.3.2.dev102.dist-info/RECORD,,