deucebucket's picture
clanker hackathon gradio entry (verification copy)
ecca2a3 verified
Raw
History Blame Contribute Delete
5.82 kB
"""Pipeline debug trace — watch each engine stage in real time.
Every stage in the pipeline logs what it did: inputs, decisions, outputs.
Enable with `compute_vadug(text, trace=True)` or `Pipeline(trace=True)`.
Usage:
from engine.pendulum import compute_vadug
# Normal (no trace):
vadug, meta = compute_vadug("im fine")
# With trace:
vadug, meta = compute_vadug("im fine", trace=True)
for entry in meta["pipeline_trace"]:
print(f"[{entry['stage']}] {entry['summary']}")
# Pretty print:
from engine.trace import print_trace
print_trace(meta["pipeline_trace"])
"""
from dataclasses import dataclass, field
from typing import List, Any
@dataclass
class TraceEntry:
"""One stage's contribution to the pipeline trace."""
stage: str # TOKENIZE, CLASSIFY, PROXIMITY, FORCES, etc.
summary: str # one-line human-readable summary
details: dict = field(default_factory=dict) # full data for debugging
input_state: dict = field(default_factory=dict) # state BEFORE this stage
output_state: dict = field(default_factory=dict) # state AFTER this stage
class PipelineTrace:
"""Accumulates trace entries across pipeline stages."""
def __init__(self, enabled: bool = False):
self.enabled = enabled
self.entries: List[TraceEntry] = []
def log(self, stage: str, summary: str, **kwargs):
"""Log a trace entry. No-op if tracing is disabled."""
if not self.enabled:
return
self.entries.append(TraceEntry(
stage=stage,
summary=summary,
details=kwargs.get("details", {}),
input_state=kwargs.get("input_state", {}),
output_state=kwargs.get("output_state", {}),
))
def to_list(self) -> list:
"""Export trace as list of dicts (for meta["pipeline_trace"])."""
return [
{
"stage": e.stage,
"summary": e.summary,
"details": e.details,
"input_state": e.input_state,
"output_state": e.output_state,
}
for e in self.entries
]
def print_trace(trace_list: list, verbose: bool = False):
"""Pretty-print a pipeline trace."""
for entry in trace_list:
stage = entry["stage"]
summary = entry["summary"]
print(f" [{stage:12s}] {summary}")
if verbose and entry.get("details"):
for k, v in entry["details"].items():
print(f" {'':14s} {k}: {v}")
# ── Stage-specific trace helpers ──────────────────────────────
def trace_tokenize(trace: PipelineTrace, words_in: list, words_out: list, compounds: list):
"""Log tokenization stage."""
if not compounds:
trace.log("TOKENIZE", f"{len(words_in)} words, no compounds")
else:
trace.log("TOKENIZE",
f"{len(words_in)}{len(words_out)} words, compounds: {compounds}",
details={"compounds": compounds})
def trace_classify(trace: PipelineTrace, roles: list):
"""Log classification stage."""
role_counts = {}
for r in roles:
role_counts[r.role] = role_counts.get(r.role, 0) + 1
emotional = [r for r in roles if r.role == "EMOTIONAL"]
trace.log("CLASSIFY",
f"{len(roles)} words: {dict(role_counts)}",
details={"emotional_words": [(r.word, r.force[0] if r.force else 0) for r in emotional]})
def trace_proximity(trace: PipelineTrace, word: str, role: str, coeff: float, force: tuple):
"""Log proximity coefficient for one word."""
if abs(coeff - 1.0) > 0.05 or (force and abs(force[0]) > 10):
trace.log("PROXIMITY",
f"{word}({role}): coeff={coeff:.2f}, dV={force[0] if force else 0:+d}",
details={"word": word, "coefficient": round(coeff, 3)})
def trace_forces(trace: PipelineTrace, state_v: float, state_a: float, state_d: float,
state_w: float, m_eff: float):
"""Log force accumulation result."""
trace.log("FORCES",
f"V={state_v:.0f} A={state_a:.0f} D={state_d:.0f} W={state_w:.0f} M_eff={m_eff:.3f}",
output_state={"V": round(state_v), "A": round(state_a),
"D": round(state_d), "W": round(state_w)})
def trace_structure(trace: PipelineTrace, pattern: str, confidence: float,
v_weight: float, state_v_before: float, state_v_after: float):
"""Log a structural pattern firing."""
trace.log("STRUCTURE",
f"{pattern} (conf={confidence:.2f}, v_weight={v_weight:+.0f}) "
f"V: {state_v_before:.0f}{state_v_after:.0f}",
details={"pattern": pattern, "confidence": confidence, "v_weight": v_weight})
def trace_anomaly(trace: PipelineTrace, anomaly_type: str, severity: int, description: str):
"""Log an anomaly detection."""
trace.log("ANOMALY",
f"[{anomaly_type}] severity={severity}: {description[:60]}",
details={"type": anomaly_type, "severity": severity})
def trace_saturate(trace: PipelineTrace, state_v_before: float, state_v_after: float):
"""Log tanh saturation effect."""
delta = abs(state_v_after - state_v_before)
if delta > 1:
trace.log("SATURATE",
f"V: {state_v_before:.0f}{state_v_after:.0f} (compressed {delta:.0f})",
details={"before": round(state_v_before), "after": round(state_v_after)})
else:
trace.log("SATURATE", "no compression needed")
def trace_final(trace: PipelineTrace, vadug):
"""Log final VADUGWI output."""
trace.log("OUTPUT",
f"V={vadug.v} A={vadug.a} D={vadug.d} U={vadug.u} G={vadug.g} W={vadug.w} I={vadug.i}")