Download code/models/common/llm_runtime/execution.py from tt-hous/clef: direct link, hf CLI and curl.
- Browser
- Download file 33 kB
-
https://huggingface.co/tt-hous/clef/resolve/main/code/models/common/llm_runtime/execution.py
- Command line
-
hf download hf://tt-hous/clef/code/models/common/llm_runtime/execution.py
-
curl -L -o execution.py https://huggingface.co/tt-hous/clef/resolve/main/code/models/common/llm_runtime/execution.py
33 kB
| # SPDX-FileCopyrightText: © 2026 Tenstorrent AI ULC | |
| # SPDX-License-Identifier: Apache-2.0 | |
| """Concrete eager and traced execution by direct composition.""" | |
| from __future__ import annotations | |
| import json | |
| from collections.abc import Sequence | |
| from dataclasses import asdict, dataclass | |
| from typing import Any | |
| import torch | |
| from loguru import logger | |
| from models.common.llm_runtime.decode import DecodeRuntime | |
| from models.common.llm_runtime.decode import InvocationResult as DecodeInvocationResult | |
| from models.common.llm_runtime.prefill.plan import PrefillRequest | |
| from models.common.llm_runtime.prefill.runtime import PrefillRuntime | |
| from models.common.llm_runtime.program_compiler import CompiledProgram, OutputSpec, ProgramCompiler | |
| from models.common.llm_runtime.trace_compiler import InputRefreshPolicy, TraceCapturePlan, TraceCompiler | |
| class TraceCoverageError(RuntimeError): | |
| """Actionable strict-trace miss with construction coverage context.""" | |
| class PrefillReplayEvidence: | |
| """Structured evidence for one successfully submitted prefill trace.""" | |
| operation: str | |
| variant: str | |
| sampling_path: str | |
| execution: str | |
| active_batch_size: int | |
| padded_batch_size: int | |
| padded_sequence_length: int | |
| lane: int | |
| rank: int | |
| program_key: str | |
| trace_key: str | |
| replay_steps: int | |
| class EagerExecutor: | |
| """Compile and execute prepared requests through the eager TT path. | |
| ``Llama3Executor`` owns one instance and exposes it to | |
| ``Llama3Generator`` as the non-traced execution target. Callers normally | |
| use `compile_prefill`, `prefill_forward`, | |
| `compile_decode`, and `decode_forward`; request preparation and | |
| program-registry mechanics remain private to this composition. | |
| """ | |
| def __init__(self, *, prefill: PrefillRuntime, decode: DecodeRuntime, program_compiler: ProgramCompiler) -> None: | |
| if not isinstance(prefill, PrefillRuntime): | |
| raise TypeError("prefill must be a PrefillRuntime") | |
| if not isinstance(decode, DecodeRuntime): | |
| raise TypeError("decode must be a DecodeRuntime") | |
| if not isinstance(program_compiler, ProgramCompiler): | |
| raise TypeError("program_compiler must be a ProgramCompiler") | |
| self.prefill = prefill | |
| self.decode = decode | |
| self.program_compiler = program_compiler | |
| self._eager_prefill_count = 0 | |
| # Public API | |
| def eager_prefill_count(self) -> int: | |
| """Return successfully submitted eager prefill requests.""" | |
| return self._eager_prefill_count | |
| def runtime_summary(self) -> dict[str, Any]: | |
| """Return serving-gate counters owned by the eager execution path.""" | |
| return { | |
| "eager_prefill_executions": self._eager_prefill_count, | |
| "semantic_program_count": len(self.program_compiler.compiled_programs), | |
| "rejected_post_activation_compile_attempts": (self.program_compiler.post_activation_compile_rejections), | |
| "ttnn_program_cache_count": _program_cache_entries(self.program_compiler.mesh_device), | |
| } | |
| def compile_prefill( | |
| self, | |
| *, | |
| tokens: torch.Tensor, # ↓ Core request | |
| page_table: torch.Tensor, | |
| prompt_lens: torch.Tensor | None = None, # ↓ Sequence metadata | |
| start_pos: torch.Tensor | None = None, | |
| empty_slots: Sequence[int] | None = None, # ↓ Lane routing | |
| sampling_params: Any = None, # ↓ Sampling | |
| prompt_tokens: Any = None, # ↓ Request-owned sampling state | |
| output_tokens: Any = None, | |
| slot_remap: Any = None, | |
| ) -> tuple[CompiledProgram, ...]: | |
| """Prepare and compile every eager program needed by one prefill call.""" | |
| programs = [] | |
| for prepared in self._prepare_prefill( | |
| tokens=tokens, | |
| page_table=page_table, | |
| prompt_lens=prompt_lens, | |
| start_pos=start_pos, | |
| empty_slots=empty_slots, | |
| sampling_params=sampling_params, | |
| prompt_tokens=prompt_tokens, | |
| output_tokens=output_tokens, | |
| slot_remap=slot_remap, | |
| ): | |
| programs.extend(self._compile_prefill(prepared)) | |
| return tuple(programs) | |
| def prefill_forward( | |
| self, | |
| *, | |
| tokens: torch.Tensor, # ↓ Core request | |
| page_table: torch.Tensor, | |
| prompt_lens: torch.Tensor | None = None, # ↓ Sequence metadata | |
| start_pos: torch.Tensor | None = None, | |
| empty_slots: Sequence[int] | None = None, # ↓ Lane routing | |
| sampling_params: Any = None, # ↓ Sampling | |
| prompt_tokens: Any = None, # ↓ Request-owned sampling state | |
| output_tokens: Any = None, | |
| slot_remap: Any = None, | |
| ): | |
| """Prepare, execute, and assemble one eager prefill call.""" | |
| prepared = self._prepare_prefill( | |
| tokens=tokens, | |
| page_table=page_table, | |
| prompt_lens=prompt_lens, | |
| start_pos=start_pos, | |
| empty_slots=empty_slots, | |
| sampling_params=sampling_params, | |
| prompt_tokens=prompt_tokens, | |
| output_tokens=output_tokens, | |
| slot_remap=slot_remap, | |
| ) | |
| results = tuple((request, self._execute_prefill(request)) for request in prepared) | |
| return self.prefill.assemble( | |
| results, | |
| batch_size=int(tokens.shape[0]), | |
| sampling_params=sampling_params, | |
| ) | |
| def compile_decode( | |
| self, | |
| *, | |
| tokens: torch.Tensor, # ↓ Core request | |
| start_pos: torch.Tensor, | |
| page_table: torch.Tensor, | |
| sampling_params: Any = None, # ↓ Sampling | |
| prompt_tokens: Any = None, # ↓ Request-owned sampling state | |
| output_tokens: Any = None, | |
| slot_remap: Any = None, | |
| reset_batch: bool = False, # ↓ State transition | |
| ) -> CompiledProgram: | |
| """Prepare and compile the eager program needed by one decode call.""" | |
| return self._compile_decode( | |
| self._prepare_decode( | |
| tokens=tokens, | |
| start_pos=start_pos, | |
| page_table=page_table, | |
| sampling_params=sampling_params, | |
| prompt_tokens=prompt_tokens, | |
| output_tokens=output_tokens, | |
| slot_remap=slot_remap, | |
| reset_batch=reset_batch, | |
| ) | |
| ) | |
| def decode_forward( | |
| self, | |
| *, | |
| tokens: torch.Tensor, # ↓ Core request | |
| start_pos: torch.Tensor, | |
| page_table: torch.Tensor, | |
| sampling_params: Any = None, # ↓ Sampling | |
| prompt_tokens: Any = None, # ↓ Request-owned sampling state | |
| output_tokens: Any = None, | |
| slot_remap: Any = None, | |
| reset_batch: bool = False, # ↓ State transition | |
| read_from_device: bool = True, # ↓ Output policy | |
| ): | |
| """Prepare and execute one eager decode call.""" | |
| prepared = self._prepare_decode( | |
| tokens=tokens, | |
| start_pos=start_pos, | |
| page_table=page_table, | |
| sampling_params=sampling_params, | |
| prompt_tokens=prompt_tokens, | |
| output_tokens=output_tokens, | |
| slot_remap=slot_remap, | |
| reset_batch=reset_batch, | |
| ) | |
| return self._execute_decode(prepared, read_from_device=read_from_device) | |
| # Private implementation | |
| def _prepare_prefill( | |
| self, | |
| *, | |
| tokens: torch.Tensor, # ↓ Core request | |
| page_table: torch.Tensor, | |
| prompt_lens: torch.Tensor | None = None, # ↓ Sequence metadata | |
| start_pos: torch.Tensor | None = None, | |
| empty_slots: Sequence[int] | None = None, # ↓ Lane routing | |
| sampling_params: Any = None, # ↓ Sampling | |
| prompt_tokens: Any = None, # ↓ Request-owned sampling state | |
| output_tokens: Any = None, | |
| slot_remap: Any = None, | |
| ): | |
| kwargs: dict[str, Any] = { | |
| "tokens": tokens, | |
| "page_table": page_table, | |
| "prompt_lens": prompt_lens, | |
| "start_pos": start_pos, | |
| "empty_slots": empty_slots, | |
| "sampling_params": sampling_params, | |
| } | |
| for name, value in ( | |
| ("prompt_tokens", prompt_tokens), | |
| ("output_tokens", output_tokens), | |
| ("slot_remap", slot_remap), | |
| ): | |
| if value is not None: | |
| kwargs[name] = value | |
| return self.prefill.prepare(**kwargs) | |
| def _compile_prefill(self, prepared: Any): | |
| programs = [] | |
| for signature in prepared.program_signatures: | |
| programs.append( | |
| self.program_compiler.compile( | |
| signature, | |
| lambda _context, prepared=prepared: self.prefill.invoke(prepared, count_tokens=False), | |
| output_spec=lambda result: OutputSpec.from_value(result.value), | |
| release_output=lambda result: result.owned, | |
| ) | |
| ) | |
| return tuple(programs) | |
| def _execute_prefill(self, prepared: Any): | |
| self._require_ready_after_trace_gate(prepared.program_signatures) | |
| result = self.prefill.invoke(prepared) | |
| self._eager_prefill_count += 1 | |
| return result | |
| def _prepare_decode( | |
| self, | |
| *, | |
| tokens: torch.Tensor, # ↓ Core request | |
| start_pos: torch.Tensor, | |
| page_table: torch.Tensor, | |
| sampling_params: Any = None, # ↓ Sampling | |
| prompt_tokens: Any = None, # ↓ Request-owned sampling state | |
| output_tokens: Any = None, | |
| slot_remap: Any = None, | |
| reset_batch: bool = False, # ↓ State transition | |
| ): | |
| kwargs: dict[str, Any] = { | |
| "tokens": tokens, | |
| "start_pos": start_pos, | |
| "page_table": page_table, | |
| "sampling_params": sampling_params, | |
| "reset_batch": reset_batch, | |
| } | |
| for name, value in ( | |
| ("prompt_tokens", prompt_tokens), | |
| ("output_tokens", output_tokens), | |
| ("slot_remap", slot_remap), | |
| ): | |
| if value is not None: | |
| kwargs[name] = value | |
| return self.decode.prepare(**kwargs) | |
| def _compile_decode(self, prepared: Any): | |
| return self.program_compiler.compile( | |
| self.decode.program_signature(prepared), | |
| lambda _context: self.decode.invoke( | |
| prepared, | |
| device_feedback=prepared.device_feedback, | |
| count_tokens=False, | |
| ), | |
| output_spec=lambda result: OutputSpec.from_value(result.value), | |
| release_output=lambda result: result.owned, | |
| ) | |
| def _execute_decode(self, prepared: Any, *, read_from_device: bool = True): | |
| if self._program_gate_active(): | |
| self._require_ready_after_trace_gate((self.decode.program_signature(prepared),)) | |
| result = self.decode.invoke(prepared, device_feedback=False) | |
| return self.decode.consume(result, read_from_device=read_from_device) | |
| def _require_ready_after_trace_gate(self, signatures: Any) -> None: | |
| if not self._program_gate_active(): | |
| return | |
| for signature in signatures: | |
| key = self.program_compiler.key_for(signature) | |
| self.program_compiler.require_compiled(key, signature) | |
| def _program_gate_active(self) -> bool: | |
| return self.program_compiler.trace_capture_in_progress or self.program_compiler.trace_active | |
| class TracedExecutor: | |
| """Compile and replay traces over one exact `EagerExecutor`. | |
| ``Llama3Generator`` selects this target only when the requested operation | |
| is configured and eligible for tracing. This class never chooses an eager | |
| fallback; a caller that wants eager execution uses | |
| `eager_executor` directly. | |
| """ | |
| def __init__(self, *, eager: EagerExecutor, trace_compiler: TraceCompiler, trace_mode: str = "all") -> None: | |
| if not isinstance(eager, EagerExecutor): | |
| raise TypeError("eager must be an EagerExecutor") | |
| if not isinstance(trace_compiler, TraceCompiler): | |
| raise TypeError("trace_compiler must be a TraceCompiler") | |
| if trace_compiler.program_compiler is not eager.program_compiler: | |
| raise ValueError("trace_compiler must compose eager.program_compiler") | |
| if trace_mode not in ("decode_only", "all"): | |
| raise ValueError("TracedExecutor trace_mode must be 'decode_only' or 'all'") | |
| self.eager_executor = eager | |
| self.trace_compiler = trace_compiler | |
| self.trace_mode = trace_mode | |
| self._coverage_miss_count = 0 | |
| self._recent_prefill_replay_evidence: tuple[PrefillReplayEvidence, ...] = () | |
| def coverage_miss_count(self) -> int: | |
| """Return strict operation coverage misses rejected before replay.""" | |
| return self._coverage_miss_count | |
| def recent_prefill_replay_evidence(self) -> tuple[PrefillReplayEvidence, ...]: | |
| """Return evidence emitted by the most recent prepared public call.""" | |
| return self._recent_prefill_replay_evidence | |
| def runtime_summary(self) -> dict[str, Any]: | |
| """Return the end-of-run counters required by serving qualification.""" | |
| summary = self.eager_executor.runtime_summary() | |
| summary.update( | |
| { | |
| "successful_trace_replays": self.trace_compiler.replay_count, | |
| "trace_replays_by_operation": self.trace_compiler.replay_counts, | |
| "strict_coverage_misses": self._coverage_miss_count, | |
| "semantic_trace_count": self.trace_compiler.trace_count, | |
| "trace_association_count": self.trace_compiler.trace_association_count, | |
| } | |
| ) | |
| return summary | |
| def log_runtime_summary(self, *, phase: str | None = None) -> dict[str, Any]: | |
| """Emit and return one structured serving-lifecycle summary.""" | |
| summary = self.runtime_summary() | |
| if phase is not None: | |
| summary["phase"] = phase | |
| logger.info("TTTV2_RUNTIME_SUMMARY {}", json.dumps(summary, sort_keys=True)) | |
| return summary | |
| # Public API | |
| def compile_prefill( | |
| self, | |
| *, | |
| tokens: torch.Tensor, # ↓ Core request | |
| page_table: torch.Tensor, | |
| prompt_lens: torch.Tensor | None = None, # ↓ Sequence metadata | |
| start_pos: torch.Tensor | None = None, | |
| empty_slots: Sequence[int] | None = None, # ↓ Lane routing | |
| sampling_params: Any = None, # ↓ Sampling | |
| prompt_tokens: Any = None, # ↓ Request-owned sampling state | |
| output_tokens: Any = None, | |
| slot_remap: Any = None, | |
| ) -> tuple[CompiledProgram, ...]: | |
| """Compile eager prefill programs and register their trace plans.""" | |
| programs = [] | |
| for prepared in self.eager_executor._prepare_prefill( | |
| tokens=tokens, | |
| page_table=page_table, | |
| prompt_lens=prompt_lens, | |
| start_pos=start_pos, | |
| empty_slots=empty_slots, | |
| sampling_params=sampling_params, | |
| prompt_tokens=prompt_tokens, | |
| output_tokens=output_tokens, | |
| slot_remap=slot_remap, | |
| ): | |
| programs.extend(self._compile_prefill(prepared)) | |
| return tuple(programs) | |
| def prefill_forward( | |
| self, | |
| *, | |
| tokens: torch.Tensor, # ↓ Core request | |
| page_table: torch.Tensor, | |
| prompt_lens: torch.Tensor | None = None, # ↓ Sequence metadata | |
| start_pos: torch.Tensor | None = None, | |
| empty_slots: Sequence[int] | None = None, # ↓ Lane routing | |
| sampling_params: Any = None, # ↓ Sampling | |
| prompt_tokens: Any = None, # ↓ Request-owned sampling state | |
| output_tokens: Any = None, | |
| slot_remap: Any = None, | |
| ): | |
| """Replay traced prefill and assemble the results.""" | |
| prepared = self.prepare_prefill( | |
| tokens=tokens, | |
| page_table=page_table, | |
| prompt_lens=prompt_lens, | |
| start_pos=start_pos, | |
| empty_slots=empty_slots, | |
| sampling_params=sampling_params, | |
| prompt_tokens=prompt_tokens, | |
| output_tokens=output_tokens, | |
| slot_remap=slot_remap, | |
| ) | |
| preflighted = self.preflight_prefill(prepared) | |
| return self.execute_prepared_prefill( | |
| preflighted, | |
| batch_size=int(tokens.shape[0]), | |
| sampling_params=sampling_params, | |
| ) | |
| def prepare_prefill( | |
| self, | |
| *, | |
| tokens: torch.Tensor, | |
| page_table: torch.Tensor, | |
| prompt_lens: torch.Tensor | None = None, | |
| start_pos: torch.Tensor | None = None, | |
| empty_slots: Sequence[int] | None = None, | |
| sampling_params: Any = None, | |
| prompt_tokens: Any = None, | |
| output_tokens: Any = None, | |
| slot_remap: Any = None, | |
| ) -> tuple[Any, ...]: | |
| """Prepare one traced public call without submitting device work.""" | |
| return tuple( | |
| self.eager_executor._prepare_prefill( | |
| tokens=tokens, | |
| page_table=page_table, | |
| prompt_lens=prompt_lens, | |
| start_pos=start_pos, | |
| empty_slots=empty_slots, | |
| sampling_params=sampling_params, | |
| prompt_tokens=prompt_tokens, | |
| output_tokens=output_tokens, | |
| slot_remap=slot_remap, | |
| ) | |
| ) | |
| def preflight_prefill(self, prepared: Sequence[Any]) -> tuple[tuple[Any, Any], ...]: | |
| """Resolve complete trace coverage for already-prepared requests.""" | |
| # Validate the complete public call before the first replay can write | |
| # KV. In particular, a later bucket/chunk trace miss must not leave an | |
| # earlier prepared item partially committed. | |
| return tuple((request, self._preflight_prefill(request)) for request in prepared) | |
| def execute_prepared_prefill( | |
| self, | |
| preflighted: Sequence[tuple[Any, Any]], | |
| *, | |
| batch_size: int, | |
| sampling_params: Any = None, | |
| lane: int = 0, | |
| ): | |
| """Replay an exact prepared/preflighted call without replanning it.""" | |
| evidence: list[PrefillReplayEvidence] = [] | |
| self._recent_prefill_replay_evidence = () | |
| # A trace record owns one persistent output buffer. Consume each replay | |
| # before the next request with the same trace overwrites that buffer. | |
| results = ( | |
| (request, self._execute_prefill(request, coverage, lane=lane, evidence=evidence)) | |
| for request, coverage in preflighted | |
| ) | |
| result = self.eager_executor.prefill.assemble( | |
| results, | |
| batch_size=batch_size, | |
| sampling_params=sampling_params, | |
| ) | |
| self._recent_prefill_replay_evidence = tuple(evidence) | |
| return result | |
| def compile_decode( | |
| self, | |
| *, | |
| tokens: torch.Tensor, # ↓ Core request | |
| start_pos: torch.Tensor, | |
| page_table: torch.Tensor, | |
| sampling_params: Any = None, # ↓ Sampling | |
| prompt_tokens: Any = None, # ↓ Request-owned sampling state | |
| output_tokens: Any = None, | |
| slot_remap: Any = None, | |
| reset_batch: bool = False, # ↓ State transition | |
| ) -> CompiledProgram: | |
| """Compile the eager decode program and register its trace plan.""" | |
| return self._compile_decode( | |
| self.eager_executor._prepare_decode( | |
| tokens=tokens, | |
| start_pos=start_pos, | |
| page_table=page_table, | |
| sampling_params=sampling_params, | |
| prompt_tokens=prompt_tokens, | |
| output_tokens=output_tokens, | |
| slot_remap=slot_remap, | |
| reset_batch=reset_batch, | |
| ) | |
| ) | |
| def decode_forward( | |
| self, | |
| *, | |
| tokens: torch.Tensor, # ↓ Core request | |
| start_pos: torch.Tensor, | |
| page_table: torch.Tensor, | |
| sampling_params: Any = None, # ↓ Sampling | |
| prompt_tokens: Any = None, # ↓ Request-owned sampling state | |
| output_tokens: Any = None, | |
| slot_remap: Any = None, | |
| reset_batch: bool = False, # ↓ State transition | |
| read_from_device: bool = True, # ↓ Output policy | |
| ): | |
| """Replay one traced decode step and consume its output.""" | |
| prepared = self.eager_executor._prepare_decode( | |
| tokens=tokens, | |
| start_pos=start_pos, | |
| page_table=page_table, | |
| sampling_params=sampling_params, | |
| prompt_tokens=prompt_tokens, | |
| output_tokens=output_tokens, | |
| slot_remap=slot_remap, | |
| reset_batch=reset_batch, | |
| ) | |
| return self._execute_decode( | |
| prepared, | |
| read_from_device=read_from_device, | |
| ) | |
| # Private implementation | |
| def _compile_prefill(self, prepared: Any): | |
| programs = self.eager_executor._compile_prefill(prepared) | |
| for program in programs: | |
| if self.trace_compiler.trace_key_for_program(program.key) is not None: | |
| continue | |
| operation_plan = self.eager_executor.prefill.capture_plan(prepared) | |
| self.trace_compiler.register_capture_plan( | |
| TraceCapturePlan( | |
| program_key=program.key, | |
| trace_signature=operation_plan.signature, | |
| operation="prefill", | |
| prepare_inputs=operation_plan.prepare_inputs, | |
| capture=lambda persistent, plan=operation_plan: plan.capture(persistent.values), | |
| refresh_policy=InputRefreshPolicy(every_replay=operation_plan.refresh_fields), | |
| schema_fingerprint=getattr(operation_plan, "schema_fingerprint", None), | |
| prepare_workspace=getattr(operation_plan, "prepare_workspace", None), | |
| workspace_fingerprint=getattr(operation_plan, "workspace_fingerprint", None), | |
| prime=( | |
| (lambda persistent, plan=operation_plan: plan.prime(persistent.values)) | |
| if operation_plan.prime is not None | |
| else None | |
| ), | |
| release_prime_output=operation_plan.release_prime_output, | |
| ) | |
| ) | |
| return programs | |
| def _preflight_prefill(self, prepared: Any): | |
| # A compiled eager program can share geometry with a request that is not | |
| # trace-eligible. Program-key equality alone must never authorize replay. | |
| if prepared.trace_signature is None: | |
| self._raise_prefill_coverage_error( | |
| prepared, | |
| reason="the prepared request is not trace-eligible", | |
| ) | |
| coverage = [] | |
| for signature in prepared.program_signatures: | |
| program_key = self.eager_executor.program_compiler.key_for(signature) | |
| trace_key = self.trace_compiler.trace_key_for_program(program_key) | |
| record = self.trace_compiler.get(trace_key) if trace_key is not None else None | |
| if record is None or record.artifact is None: | |
| self._raise_prefill_coverage_error( | |
| prepared, | |
| signature=signature, | |
| program_key=program_key, | |
| trace_key=trace_key, | |
| reason="the required trace is not registered and captured", | |
| ) | |
| coverage.append((program_key, record)) | |
| return tuple(coverage) | |
| def _execute_prefill( | |
| self, | |
| prepared: Any, | |
| coverage: Any = None, | |
| *, | |
| lane: int = 0, | |
| evidence: list[PrefillReplayEvidence] | None = None, | |
| ): | |
| coverage = self._preflight_prefill(prepared) if coverage is None else coverage | |
| if len(coverage) != 1: | |
| raise RuntimeError("Traced chunk replay requires one shared program geometry per prepared request") | |
| program_key, record = coverage[0] | |
| prefill = self.eager_executor.prefill | |
| canonical_workspace = hasattr(prepared, "request") | |
| workspace = ( | |
| self.trace_compiler.workspace_for_program(program_key) | |
| if canonical_workspace | |
| else record.artifact.persistent_inputs.values | |
| ) | |
| steps = prepared.request.chunks if hasattr(prepared, "request") else (None,) | |
| hidden = None | |
| for chunk in steps: | |
| hidden = self.trace_compiler.replay( | |
| program_key, | |
| lambda artifact, _decision, chunk=chunk: ( | |
| prefill.refresh_trace(prepared, artifact.persistent_inputs.values, workspace, chunk) | |
| if canonical_workspace and chunk is not None | |
| else ( | |
| prefill.refresh_trace(prepared, artifact.persistent_inputs.values, workspace) | |
| if canonical_workspace | |
| else prefill.refresh_trace(prepared, artifact.persistent_inputs.values) | |
| ) | |
| ), | |
| reset_batch=True, | |
| ) | |
| if hidden is None: | |
| raise RuntimeError("Prepared prefill trace sequence contained no replay steps") | |
| result = self.eager_executor.prefill.finish_trace( | |
| prepared, | |
| hidden, | |
| workspace, | |
| ) | |
| if isinstance(getattr(prepared, "request", None), PrefillRequest): | |
| request = prepared.request | |
| trace_key = self.trace_compiler.trace_key_for_program(program_key) | |
| signature = prepared.program_signatures[0] | |
| item = PrefillReplayEvidence( | |
| operation="prefill", | |
| variant=str(signature.operation_variant), | |
| sampling_path=str(prepared.sampling_path), | |
| execution="trace_replay", | |
| active_batch_size=len(request.source_rows), | |
| padded_batch_size=int(request.padded_batch_size), | |
| padded_sequence_length=int(request.padded_sequence_length), | |
| lane=int(lane), | |
| rank=int(lane), | |
| program_key=program_key.digest, | |
| trace_key="unassociated" if trace_key is None else trace_key.digest, | |
| replay_steps=len(steps), | |
| ) | |
| if evidence is not None: | |
| evidence.append(item) | |
| logger.info("TTTV2_RUNTIME_EVIDENCE {}", json.dumps(asdict(item), sort_keys=True)) | |
| return result | |
| def _raise_prefill_coverage_error( | |
| self, | |
| prepared: Any, | |
| *, | |
| reason: str, | |
| signature: Any = None, | |
| program_key: Any = None, | |
| trace_key: Any = None, | |
| ) -> None: | |
| self._coverage_miss_count += 1 | |
| model = getattr(getattr(self.eager_executor.prefill, "config", None), "model", None) | |
| model_identity = ( | |
| f"{type(model).__module__}.{type(model).__qualname__}" | |
| if model is not None | |
| else type(self.eager_executor.prefill).__qualname__ | |
| ) | |
| exact_signature = signature if signature is not None else getattr(prepared, "trace_signature", None) | |
| if exact_signature is None: | |
| exact_signature = tuple(getattr(prepared, "program_signatures", ())) | |
| material = _signature_material(exact_signature) | |
| configured = tuple( | |
| { | |
| "trace_key": key.digest, | |
| "signature": _signature_material(registered_signature), | |
| } | |
| for key, registered_signature in self.trace_compiler.registered_coverage("prefill") | |
| ) | |
| digest = getattr(program_key, "digest", "unavailable") | |
| associated_trace = getattr(trace_key, "digest", "unavailable") | |
| raise TraceCoverageError( | |
| "Required prefill trace is unavailable: " | |
| f"reason={reason}; operation=prefill; trace_mode={self.trace_mode}; model={model_identity}; " | |
| f"signature_material={material!r}; signature_digest={digest}; " | |
| f"program_key={digest}; trace_key={associated_trace}; configured_coverage={configured!r}. " | |
| "Add the missing signature to construction-time trace coverage, or rerun with " | |
| "TraceConfig(mode='none') for debugging." | |
| ) | |
| def _compile_decode(self, prepared: Any): | |
| program = self.eager_executor._compile_decode(prepared) | |
| if self.trace_compiler.trace_key_for_program(program.key) is None: | |
| operation_plan = self.eager_executor.decode.capture_plan(prepared) | |
| self.trace_compiler.register_capture_plan( | |
| TraceCapturePlan( | |
| program_key=program.key, | |
| trace_signature=self.eager_executor.decode.trace_signature(prepared), | |
| operation="decode", | |
| prepare_inputs=operation_plan.prepare_inputs, | |
| capture=lambda persistent, plan=operation_plan: plan.capture(persistent.values), | |
| refresh_policy=InputRefreshPolicy( | |
| every_replay=operation_plan.refresh_policy.every_replay, | |
| full_on_batch_reset=operation_plan.refresh_policy.full_on_batch_reset, | |
| full_on_graph_switch=operation_plan.refresh_policy.full_on_graph_switch, | |
| full_without_device_feedback=operation_plan.refresh_policy.full_without_device_feedback, | |
| refresh_page_table_on_change=operation_plan.refresh_policy.refresh_page_table_on_change, | |
| ), | |
| ) | |
| ) | |
| return program | |
| def _execute_decode(self, prepared: Any, *, read_from_device: bool = True): | |
| decode = self.eager_executor.decode | |
| signature = decode.program_signature(prepared) | |
| program_key = self.eager_executor.program_compiler.key_for(signature) | |
| trace_key = self.trace_compiler.trace_key_for_program(program_key) | |
| record = self.trace_compiler.get(trace_key) if trace_key is not None else None | |
| if record is None or record.artifact is None: | |
| self._coverage_miss_count += 1 | |
| model = getattr(getattr(decode, "config", None), "model", None) | |
| model_identity = ( | |
| f"{type(model).__module__}.{type(model).__qualname__}" | |
| if model is not None | |
| else type(decode).__qualname__ | |
| ) | |
| configured = tuple( | |
| { | |
| "trace_key": key.digest, | |
| "signature": _signature_material(registered_signature), | |
| } | |
| for key, registered_signature in self.trace_compiler.registered_coverage("decode") | |
| ) | |
| associated_trace = "unavailable" if trace_key is None else trace_key.digest | |
| raise TraceCoverageError( | |
| "Required decode trace is unavailable: operation=decode; " | |
| f"trace_mode={self.trace_mode}; model={model_identity}; " | |
| f"signature_material={_signature_material(signature)!r}; " | |
| f"signature_digest={program_key.digest}; program_key={program_key.digest}; " | |
| f"trace_key={associated_trace}; configured_coverage={configured!r}. " | |
| "Add the missing signature to construction-time trace coverage, or rerun with " | |
| "TraceConfig(mode='none') for debugging." | |
| ) | |
| output = self.trace_compiler.replay( | |
| program_key, | |
| lambda artifact, decision: decode.refresh_trace(artifact, prepared, decision), | |
| reset_batch=prepared.reset_batch, | |
| device_feedback_enabled=decode.config.position_feedback_capable, | |
| feedback_compatible=prepared.device_feedback, | |
| page_table_changed=prepared.page_table_changed, | |
| ) | |
| decode.note_submitted(prepared) | |
| result = DecodeInvocationResult( | |
| value=output, | |
| owned=None, | |
| is_tokens=prepared.sampling_params is not None, | |
| ) | |
| return decode.consume(result, read_from_device=read_from_device) | |
| def _signature_material(signature: Any) -> Any: | |
| """Return stable diagnostic material without changing registry identity.""" | |
| if isinstance(signature, tuple): | |
| return tuple(_signature_material(value) for value in signature) | |
| material = getattr(signature, "key_material", None) | |
| if material is None: | |
| return repr(signature) | |
| return material() if callable(material) else material | |
| def _program_cache_entries(mesh_device: Any) -> int | None: | |
| """Read TTNN program-cache size when the concrete mesh exposes it.""" | |
| devices = mesh_device.get_devices() if hasattr(mesh_device, "get_devices") else (mesh_device,) | |
| counts = [] | |
| for device in devices: | |
| count = getattr(device, "num_program_cache_entries", None) | |
| if not callable(count): | |
| return None | |
| counts.append(int(count())) | |
| return sum(counts) | |