Spaces:
Sleeping
Sleeping
Commit ·
018a9f2
1
Parent(s): bff3e4d
Added pre-built prompts for app and chatbot
Browse files- RESEARCH-jargon-reduction.md +0 -78
- app.py +40 -2
- assets/style.css +62 -0
- components/chatbot.py +17 -1
- components/model_selector.py +35 -0
- debug_logs.md +0 -163
- plans.md +3 -16
- todo.md +0 -227
RESEARCH-jargon-reduction.md
DELETED
|
@@ -1,78 +0,0 @@
|
|
| 1 |
-
# RESEARCH-jargon-reduction
|
| 2 |
-
|
| 3 |
-
## Objective
|
| 4 |
-
Analyze the LLMVis project for technical jargon (e.g., "head", "ablation", "tokenizing") that may confuse younger or less technical audiences, and outline plain-English alternatives and explanations. The goal is to make the educational dashboard more accessible without completely losing technical accuracy.
|
| 5 |
-
|
| 6 |
-
## Findings: Jargon in User-Facing Components
|
| 7 |
-
|
| 8 |
-
### 1. "Ablation" / "Ablate"
|
| 9 |
-
**Locations found:**
|
| 10 |
-
- `app.py`: "Ablation" tab in the Investigation Panel
|
| 11 |
-
- `components/ablation_panel.py`: "What is Ablation?", "Add Head to Ablation List", "Run Ablation Experiment", "Ablated Output"
|
| 12 |
-
|
| 13 |
-
**Issue:** "Ablation" is a highly specialized term originally from neuroscience/medicine, adapted for machine learning to mean removing a component to observe its effect. It is completely opaque to a layperson.
|
| 14 |
-
|
| 15 |
-
**Proposed Replacements:**
|
| 16 |
-
- Replace primary "Ablation" headers with "Component Removal" or "Test by Removing".
|
| 17 |
-
- Replace "Run Ablation Experiment" with "Test What Happens When Removed".
|
| 18 |
-
- Keep "Ablation" only in an advanced glossary, a tooltip or as a secondary subtitle: "Test by Removing (Ablation)".
|
| 19 |
-
|
| 20 |
-
### 2. "Token" / "Tokenization" / "Tokenizing"
|
| 21 |
-
**Locations found:**
|
| 22 |
-
- `app.py`: "Number of New Tokens"
|
| 23 |
-
- `components/pipeline.py`: "Tokenization" pipeline stage, "Your text is split into tokens"
|
| 24 |
-
- `components/investigation_panel.py`: "Token Attribution", "Target Token"
|
| 25 |
-
|
| 26 |
-
**Issue:** While "token" is explained somewhat in the app ("pieces that the model can understand"), phrases like "Token Attribution" or "Tokenization" sound overly academic as top-level headings.
|
| 27 |
-
|
| 28 |
-
**Proposed Replacements:**
|
| 29 |
-
- Use "Text Chunking" or "Word Pieces" as the primary heading, introducing "Tokens" as the technical equivalent inside the explanation.
|
| 30 |
-
- Change "Token Attribution" to "Which words influenced the answer?" or "Word Influence Score".
|
| 31 |
-
|
| 32 |
-
### 3. "Attention Head" / "Head"
|
| 33 |
-
**Locations found:**
|
| 34 |
-
- `components/pipeline.py`: "Attention has multiple heads"
|
| 35 |
-
- `components/ablation_panel.py`: "Select heads to ablate", "Attention Head Roles"
|
| 36 |
-
|
| 37 |
-
**Issue:** "Head" in "Attention Head" is an architectural metaphor that doesn't organically mean anything to someone unfamiliar with the transformer architecture (multi-head attention).
|
| 38 |
-
|
| 39 |
-
**Proposed Replacements:**
|
| 40 |
-
- Reframe as "Attention Pattern", "Context Detector" or "Feature Spotter".
|
| 41 |
-
- Explain "Heads" as "Specialized Detectors" or "Information Filters" (e.g., "The model uses multiple 'Detectors' (called heads) to find relationships...").
|
| 42 |
-
|
| 43 |
-
### 4. "Embedding" / "Vector"
|
| 44 |
-
**Locations found:**
|
| 45 |
-
- `components/pipeline.py`: "Embedding" stage, "high-dimensional vector", "lookup table"
|
| 46 |
-
|
| 47 |
-
**Issue:** "Vector" and "high-dimensional" sound like advanced mathematical phrases which may intimidate a younger user.
|
| 48 |
-
|
| 49 |
-
**Proposed Replacements:**
|
| 50 |
-
- Instead of "Embedding", use "Meaning Translation" or "Number Dictionary".
|
| 51 |
-
- Instead of "high-dimensional vector", use "list of numbers representing meaning".
|
| 52 |
-
|
| 53 |
-
### 5. "MLP" / "Feed-Forward"
|
| 54 |
-
**Locations found:**
|
| 55 |
-
- `components/pipeline.py`: "MLP (Feed-Forward)", "MLP layers"
|
| 56 |
-
|
| 57 |
-
**Issue:** MLP (Multi-Layer Perceptron) is legacy neural network jargon that is not intuitive in the context of what it actually does (storing factual knowledge).
|
| 58 |
-
|
| 59 |
-
**Proposed Replacements:**
|
| 60 |
-
- Rename the pipeline stage to "Factual Knowledge" or "Memory Layers".
|
| 61 |
-
- Include "(MLP/Feed-Forward)" only as a small subtitle for those who want the exact technical term.
|
| 62 |
-
|
| 63 |
-
### 6. "Logit" / "Probability" / "Activation Score"
|
| 64 |
-
**Locations found:**
|
| 65 |
-
- `components/ablation_panel.py`: "Average prob shift", "activation: 85%"
|
| 66 |
-
|
| 67 |
-
**Issue:** Jargon related to raw model outputs. "Activation score" sounds like a futuristic/sci-fi term.
|
| 68 |
-
|
| 69 |
-
**Proposed Replacements:**
|
| 70 |
-
- "Activation score" -> "Confidence level" or "Strength of focus".
|
| 71 |
-
- "Average prob shift" -> "Average change in confidence".
|
| 72 |
-
|
| 73 |
-
## What Was Ruled Out
|
| 74 |
-
- **Completely eliminating all technical terms:** We ruled out removing words like "Token" or "Model" entirely because learning some valid terminology is part of the educational value of the tool. Instead, we will prioritize plain English for headings and actions, and introduce the technical terms in parentheses or explanatory sentences.
|
| 75 |
-
- **Rewriting the RAG Docs right now:** The `rag_docs/` folder contains extensive markdown documentation. For this primary pass, we ruled out modifying those long-form files, focusing entirely on the primary UI headers, buttons, and short stage descriptions in `app.py` and the `components/` directory to maximize immediate impact.
|
| 76 |
-
|
| 77 |
-
## Next Steps
|
| 78 |
-
Review this document. If these jargon replacements aligned with the intended goal for younger audiences, we can draft `SPEC-jargon-reduction.md` with explicit strings to be updated across the application.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.py
CHANGED
|
@@ -25,7 +25,7 @@ from utils.token_attribution import compute_integrated_gradients, compute_simple
|
|
| 25 |
|
| 26 |
# Import modular components
|
| 27 |
from components.sidebar import create_sidebar
|
| 28 |
-
from components.model_selector import create_model_selector
|
| 29 |
from components.glossary import create_glossary_modal
|
| 30 |
from components.pipeline import (create_pipeline_container, create_tokenization_content,
|
| 31 |
create_embedding_content, create_attention_content,
|
|
@@ -33,7 +33,7 @@ from components.pipeline import (create_pipeline_container, create_tokenization_
|
|
| 33 |
_build_token_display, _build_top5_chart)
|
| 34 |
from components.investigation_panel import create_investigation_panel, create_attribution_results_display
|
| 35 |
from components.ablation_panel import create_selected_heads_display, create_ablation_results_display
|
| 36 |
-
from components.chatbot import create_chatbot_container, render_messages
|
| 37 |
|
| 38 |
# Initialize Dash app
|
| 39 |
app = dash.Dash(
|
|
@@ -1442,6 +1442,44 @@ app.clientside_callback(
|
|
| 1442 |
)
|
| 1443 |
|
| 1444 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1445 |
if __name__ == '__main__':
|
| 1446 |
# Use 0.0.0.0:7860 for Hugging Face Spaces, fallback to localhost:8050 for local dev
|
| 1447 |
import os
|
|
|
|
| 25 |
|
| 26 |
# Import modular components
|
| 27 |
from components.sidebar import create_sidebar
|
| 28 |
+
from components.model_selector import create_model_selector, EXAMPLE_PROMPTS
|
| 29 |
from components.glossary import create_glossary_modal
|
| 30 |
from components.pipeline import (create_pipeline_container, create_tokenization_content,
|
| 31 |
create_embedding_content, create_attention_content,
|
|
|
|
| 33 |
_build_token_display, _build_top5_chart)
|
| 34 |
from components.investigation_panel import create_investigation_panel, create_attribution_results_display
|
| 35 |
from components.ablation_panel import create_selected_heads_display, create_ablation_results_display
|
| 36 |
+
from components.chatbot import create_chatbot_container, render_messages, SUGGESTED_QUESTIONS
|
| 37 |
|
| 38 |
# Initialize Dash app
|
| 39 |
app = dash.Dash(
|
|
|
|
| 1442 |
)
|
| 1443 |
|
| 1444 |
|
| 1445 |
+
# ============================================================================
|
| 1446 |
+
# EXAMPLE PROMPT CHIPS
|
| 1447 |
+
# ============================================================================
|
| 1448 |
+
|
| 1449 |
+
@callback(
|
| 1450 |
+
Output('prompt-input', 'value', allow_duplicate=True),
|
| 1451 |
+
Input({"type": "example-prompt-btn", "index": ALL}, "n_clicks"),
|
| 1452 |
+
prevent_initial_call=True
|
| 1453 |
+
)
|
| 1454 |
+
def fill_prompt_from_chip(n_clicks_list):
|
| 1455 |
+
"""Populate the prompt textarea when an example prompt chip is clicked."""
|
| 1456 |
+
if not any(n_clicks_list):
|
| 1457 |
+
return no_update
|
| 1458 |
+
triggered = dash.ctx.triggered_id
|
| 1459 |
+
if triggered and "index" in triggered:
|
| 1460 |
+
return EXAMPLE_PROMPTS[triggered["index"]]["prompt"]
|
| 1461 |
+
return no_update
|
| 1462 |
+
|
| 1463 |
+
|
| 1464 |
+
# ============================================================================
|
| 1465 |
+
# CHAT SUGGESTION CHIPS
|
| 1466 |
+
# ============================================================================
|
| 1467 |
+
|
| 1468 |
+
@callback(
|
| 1469 |
+
Output('chat-input', 'value', allow_duplicate=True),
|
| 1470 |
+
Input({"type": "chat-suggestion-btn", "index": ALL}, "n_clicks"),
|
| 1471 |
+
prevent_initial_call=True
|
| 1472 |
+
)
|
| 1473 |
+
def fill_chat_from_suggestion(n_clicks_list):
|
| 1474 |
+
"""Populate the chat textarea when a suggestion chip is clicked."""
|
| 1475 |
+
if not any(n_clicks_list):
|
| 1476 |
+
return no_update
|
| 1477 |
+
triggered = dash.ctx.triggered_id
|
| 1478 |
+
if triggered and "index" in triggered:
|
| 1479 |
+
return SUGGESTED_QUESTIONS[triggered["index"]]
|
| 1480 |
+
return no_update
|
| 1481 |
+
|
| 1482 |
+
|
| 1483 |
if __name__ == '__main__':
|
| 1484 |
# Use 0.0.0.0:7860 for Hugging Face Spaces, fallback to localhost:8050 for local dev
|
| 1485 |
import os
|
assets/style.css
CHANGED
|
@@ -1566,4 +1566,66 @@ details[open].transformer-layers-container .transformer-layers-summary::before {
|
|
| 1566 |
padding: 25px;
|
| 1567 |
overflow-y: auto;
|
| 1568 |
flex: 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1569 |
}
|
|
|
|
| 1566 |
padding: 25px;
|
| 1567 |
overflow-y: auto;
|
| 1568 |
flex: 1;
|
| 1569 |
+
}
|
| 1570 |
+
|
| 1571 |
+
/* ============================================================================
|
| 1572 |
+
EXAMPLE PROMPT CHIPS
|
| 1573 |
+
============================================================================ */
|
| 1574 |
+
|
| 1575 |
+
.example-prompts-label {
|
| 1576 |
+
font-size: 0.8rem;
|
| 1577 |
+
color: #888;
|
| 1578 |
+
margin-bottom: 6px;
|
| 1579 |
+
}
|
| 1580 |
+
|
| 1581 |
+
.example-prompts-container {
|
| 1582 |
+
display: flex;
|
| 1583 |
+
flex-wrap: wrap;
|
| 1584 |
+
gap: 8px;
|
| 1585 |
+
margin-bottom: 10px;
|
| 1586 |
+
}
|
| 1587 |
+
|
| 1588 |
+
.example-prompt-chip {
|
| 1589 |
+
border-radius: 16px;
|
| 1590 |
+
border: 1px solid #667eea;
|
| 1591 |
+
color: #667eea;
|
| 1592 |
+
background: transparent;
|
| 1593 |
+
padding: 4px 12px;
|
| 1594 |
+
font-size: 0.8rem;
|
| 1595 |
+
cursor: pointer;
|
| 1596 |
+
transition: background-color 0.2s, color 0.2s;
|
| 1597 |
+
}
|
| 1598 |
+
|
| 1599 |
+
.example-prompt-chip:hover {
|
| 1600 |
+
background-color: #667eea;
|
| 1601 |
+
color: white;
|
| 1602 |
+
}
|
| 1603 |
+
|
| 1604 |
+
/* ============================================================================
|
| 1605 |
+
CHAT SUGGESTION CHIPS
|
| 1606 |
+
============================================================================ */
|
| 1607 |
+
|
| 1608 |
+
.chat-suggestions-container {
|
| 1609 |
+
display: flex;
|
| 1610 |
+
flex-wrap: wrap;
|
| 1611 |
+
gap: 6px;
|
| 1612 |
+
padding: 8px 12px;
|
| 1613 |
+
border-bottom: 1px solid #e9ecef;
|
| 1614 |
+
}
|
| 1615 |
+
|
| 1616 |
+
.chat-suggestion-chip {
|
| 1617 |
+
border-radius: 16px;
|
| 1618 |
+
border: 1px solid #667eea;
|
| 1619 |
+
color: #667eea;
|
| 1620 |
+
background: transparent;
|
| 1621 |
+
padding: 3px 10px;
|
| 1622 |
+
font-size: 0.75rem;
|
| 1623 |
+
cursor: pointer;
|
| 1624 |
+
text-align: left;
|
| 1625 |
+
transition: background-color 0.2s, color 0.2s;
|
| 1626 |
+
}
|
| 1627 |
+
|
| 1628 |
+
.chat-suggestion-chip:hover {
|
| 1629 |
+
background-color: #667eea;
|
| 1630 |
+
color: white;
|
| 1631 |
}
|
components/chatbot.py
CHANGED
|
@@ -17,9 +17,16 @@ I can help you understand:
|
|
| 17 |
- What various experiments can reveal about model behavior
|
| 18 |
- General transformer and ML concepts
|
| 19 |
|
| 20 |
-
Try
|
| 21 |
"""
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
def create_chat_icon():
|
| 25 |
"""
|
|
@@ -158,6 +165,15 @@ def create_input_area():
|
|
| 158 |
Dash HTML component for input area
|
| 159 |
"""
|
| 160 |
return html.Div([
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
html.Div([
|
| 162 |
dcc.Textarea(
|
| 163 |
id="chat-input",
|
|
|
|
| 17 |
- What various experiments can reveal about model behavior
|
| 18 |
- General transformer and ML concepts
|
| 19 |
|
| 20 |
+
Try one of the suggestions below, or ask your own question!
|
| 21 |
"""
|
| 22 |
|
| 23 |
+
SUGGESTED_QUESTIONS = [
|
| 24 |
+
"Walk me through an example experiment step by step",
|
| 25 |
+
"What prompt should I start with and why?",
|
| 26 |
+
"What can I learn from this dashboard?",
|
| 27 |
+
"What should I look for in the attention patterns?"
|
| 28 |
+
]
|
| 29 |
+
|
| 30 |
|
| 31 |
def create_chat_icon():
|
| 32 |
"""
|
|
|
|
| 165 |
Dash HTML component for input area
|
| 166 |
"""
|
| 167 |
return html.Div([
|
| 168 |
+
html.Div([
|
| 169 |
+
html.Button(
|
| 170 |
+
q,
|
| 171 |
+
id={"type": "chat-suggestion-btn", "index": i},
|
| 172 |
+
className="chat-suggestion-chip",
|
| 173 |
+
n_clicks=0
|
| 174 |
+
)
|
| 175 |
+
for i, q in enumerate(SUGGESTED_QUESTIONS)
|
| 176 |
+
], className="chat-suggestions-container"),
|
| 177 |
html.Div([
|
| 178 |
dcc.Textarea(
|
| 179 |
id="chat-input",
|
components/model_selector.py
CHANGED
|
@@ -8,6 +8,30 @@ This component provides the interface for:
|
|
| 8 |
|
| 9 |
from dash import html, dcc
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
# Available models organized by family
|
| 12 |
AVAILABLE_MODELS = [
|
| 13 |
# GPT-2 family (OpenAI) — absolute positional encoding, LayerNorm, GELU
|
|
@@ -47,6 +71,17 @@ def create_model_selector():
|
|
| 47 |
# Prompt input
|
| 48 |
html.Div([
|
| 49 |
html.Label("Enter Prompt:", className="input-label"),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
dcc.Textarea(
|
| 51 |
id='prompt-input',
|
| 52 |
placeholder="Enter text prompt for analysis...",
|
|
|
|
| 8 |
|
| 9 |
from dash import html, dcc
|
| 10 |
|
| 11 |
+
# Example prompts for guiding users toward meaningful experiments
|
| 12 |
+
EXAMPLE_PROMPTS = [
|
| 13 |
+
{
|
| 14 |
+
"label": "Track indirect objects",
|
| 15 |
+
"prompt": "The chef gave the waiter a generous tip because",
|
| 16 |
+
"tooltip": "Tests whether the model tracks who gave and who received across clauses"
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"label": "Resolve ambiguity",
|
| 20 |
+
"prompt": "The bat flew over the",
|
| 21 |
+
"tooltip": "Tests how earlier context shapes predictions when a word has multiple meanings (bat)"
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
"label": "Understand repetition",
|
| 25 |
+
"prompt": "The cat sat on the mat. The cat sat on the",
|
| 26 |
+
"tooltip": "Activates duplicate-token and induction detectors that complete repeated sequences"
|
| 27 |
+
},
|
| 28 |
+
{
|
| 29 |
+
"label": "Link pronouns",
|
| 30 |
+
"prompt": "The nurse said that she",
|
| 31 |
+
"tooltip": "Tests coreference resolution and reveals gender bias in attention detectors"
|
| 32 |
+
}
|
| 33 |
+
]
|
| 34 |
+
|
| 35 |
# Available models organized by family
|
| 36 |
AVAILABLE_MODELS = [
|
| 37 |
# GPT-2 family (OpenAI) — absolute positional encoding, LayerNorm, GELU
|
|
|
|
| 71 |
# Prompt input
|
| 72 |
html.Div([
|
| 73 |
html.Label("Enter Prompt:", className="input-label"),
|
| 74 |
+
html.Div("Not sure what to prompt? See how models:", className="example-prompts-label"),
|
| 75 |
+
html.Div([
|
| 76 |
+
html.Button(
|
| 77 |
+
p["label"],
|
| 78 |
+
id={"type": "example-prompt-btn", "index": i},
|
| 79 |
+
className="example-prompt-chip",
|
| 80 |
+
title=p["tooltip"],
|
| 81 |
+
n_clicks=0
|
| 82 |
+
)
|
| 83 |
+
for i, p in enumerate(EXAMPLE_PROMPTS)
|
| 84 |
+
], className="example-prompts-container"),
|
| 85 |
dcc.Textarea(
|
| 86 |
id='prompt-input',
|
| 87 |
placeholder="Enter text prompt for analysis...",
|
debug_logs.md
DELETED
|
@@ -1,163 +0,0 @@
|
|
| 1 |
-
-------------------------------------------------------
|
| 2 |
-
Qwen2ForCausalLM LOAD REPORT from: Qwen/Qwen2.5-0.5B
|
| 3 |
-
Key | Status |
|
| 4 |
-
---------------+---------+-
|
| 5 |
-
lm_head.weight | MISSING |
|
| 6 |
-
|
| 7 |
-
Notes:
|
| 8 |
-
- MISSING :those params were newly initialized because missing from the checkpoint. Consider training on your downstream task.
|
| 9 |
-
-------------------------------------------------------
|
| 10 |
-
Traceback (most recent call last):
|
| 11 |
-
File "/app/app.py", line 383, in run_generation
|
| 12 |
-
results = perform_beam_search(model, tokenizer, prompt, beam_width, max_new_tokens)
|
| 13 |
-
File "/app/utils/beam_search.py", line 142, in perform_beam_search
|
| 14 |
-
outputs = model(seq)
|
| 15 |
-
File "/usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1776, in _wrapped_call_impl
|
| 16 |
-
return self._call_impl(*args, **kwargs)
|
| 17 |
-
File "/usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1787, in _call_impl
|
| 18 |
-
return forward_call(*args, **kwargs)
|
| 19 |
-
File "/usr/local/lib/python3.10/site-packages/transformers/utils/generic.py", line 843, in wrapper
|
| 20 |
-
output = func(self, *args, **kwargs)
|
| 21 |
-
File "/usr/local/lib/python3.10/site-packages/transformers/models/qwen2/modeling_qwen2.py", line 476, in forward
|
| 22 |
-
outputs: BaseModelOutputWithPast = self.model(
|
| 23 |
-
File "/usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1776, in _wrapped_call_impl
|
| 24 |
-
return self._call_impl(*args, **kwargs)
|
| 25 |
-
File "/usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1787, in _call_impl
|
| 26 |
-
return forward_call(*args, **kwargs)
|
| 27 |
-
File "/usr/local/lib/python3.10/site-packages/transformers/utils/generic.py", line 917, in wrapper
|
| 28 |
-
output = func(self, *args, **kwargs)
|
| 29 |
-
File "/usr/local/lib/python3.10/site-packages/transformers/utils/output_capturing.py", line 253, in wrapper
|
| 30 |
-
outputs = func(self, *args, **kwargs)
|
| 31 |
-
File "/usr/local/lib/python3.10/site-packages/transformers/models/qwen2/modeling_qwen2.py", line 411, in forward
|
| 32 |
-
hidden_states = decoder_layer(
|
| 33 |
-
File "/usr/local/lib/python3.10/site-packages/transformers/modeling_layers.py", line 93, in __call__
|
| 34 |
-
return super().__call__(*args, **kwargs)
|
| 35 |
-
File "/usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1776, in _wrapped_call_impl
|
| 36 |
-
return self._call_impl(*args, **kwargs)
|
| 37 |
-
File "/usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1787, in _call_impl
|
| 38 |
-
return forward_call(*args, **kwargs)
|
| 39 |
-
File "/usr/local/lib/python3.10/site-packages/transformers/models/qwen2/modeling_qwen2.py", line 298, in forward
|
| 40 |
-
hidden_states, _ = self.self_attn(
|
| 41 |
-
File "/usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1776, in _wrapped_call_impl
|
| 42 |
-
return self._call_impl(*args, **kwargs)
|
| 43 |
-
File "/usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1787, in _call_impl
|
| 44 |
-
return forward_call(*args, **kwargs)
|
| 45 |
-
File "/usr/local/lib/python3.10/site-packages/transformers/models/qwen2/modeling_qwen2.py", line 218, in forward
|
| 46 |
-
query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 47 |
-
File "/usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1776, in _wrapped_call_impl
|
| 48 |
-
return self._call_impl(*args, **kwargs)
|
| 49 |
-
File "/usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1787, in _call_impl
|
| 50 |
-
return forward_call(*args, **kwargs)
|
| 51 |
-
File "/usr/local/lib/python3.10/site-packages/torch/nn/modules/linear.py", line 134, in forward
|
| 52 |
-
return F.linear(input, self.weight, self.bias)
|
| 53 |
-
RuntimeError: mat1 and mat2 must have the same dtype, but got Float and BFloat16
|
| 54 |
-
-------------------------------------------------------
|
| 55 |
-
Qwen2ForCausalLM LOAD REPORT from: Qwen/Qwen2.5-0.5B
|
| 56 |
-
Key | Status |
|
| 57 |
-
---------------+---------+-
|
| 58 |
-
lm_head.weight | MISSING |
|
| 59 |
-
|
| 60 |
-
Notes:
|
| 61 |
-
- MISSING :those params were newly initialized because missing from the checkpoint. Consider training on your downstream task.
|
| 62 |
-
10.16.43.195 - - [19/Mar/2026 19:47:47] "POST /_dash-update-component HTTP/1.1" 200 -
|
| 63 |
-
10.16.43.195 - - [19/Mar/2026 19:47:55] "POST /_dash-update-component HTTP/1.1" 200 -
|
| 64 |
-
10.16.43.195 - - [19/Mar/2026 19:47:55] "POST /_dash-update-component HTTP/1.1" 200 -
|
| 65 |
-
Executing forward pass with prompt: 'Draw ascii art for a cat'
|
| 66 |
-
Captured 48 module outputs using PyVene
|
| 67 |
-
Loading weights: 0%| | 0/290 [00:00<?, ?it/s]10.16.31.44 - - [19/Mar/2026 19:47:55] "POST /_dash-update-component HTTP/1.1" 200 -
|
| 68 |
-
[2026-03-19 19:47:55,972] ERROR in app: Exception on /_dash-update-component [POST]
|
| 69 |
-
Traceback (most recent call last):
|
| 70 |
-
File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1511, in wsgi_app
|
| 71 |
-
response = self.full_dispatch_request()
|
| 72 |
-
File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 919, in full_dispatch_request
|
| 73 |
-
rv = self.handle_user_exception(e)
|
| 74 |
-
File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 917, in full_dispatch_request
|
| 75 |
-
rv = self.dispatch_request()
|
| 76 |
-
File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 902, in dispatch_request
|
| 77 |
-
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
|
| 78 |
-
File "/usr/local/lib/python3.10/site-packages/dash/_get_app.py", line 17, in wrap
|
| 79 |
-
return ctx.run(func, self, *args, **kwargs)
|
| 80 |
-
File "/usr/local/lib/python3.10/site-packages/dash/dash.py", line 1600, in dispatch
|
| 81 |
-
response_data = ctx.run(partial_func)
|
| 82 |
-
File "/usr/local/lib/python3.10/site-packages/dash/_callback.py", line 720, in add_context
|
| 83 |
-
raise err
|
| 84 |
-
File "/usr/local/lib/python3.10/site-packages/dash/_callback.py", line 711, in add_context
|
| 85 |
-
output_value = _invoke_callback(func, *func_args, **func_kwargs) # type: ignore[reportArgumentType]
|
| 86 |
-
File "/usr/local/lib/python3.10/site-packages/dash/_callback.py", line 58, in _invoke_callback
|
| 87 |
-
return func(*args, **kwargs) # %% callback invoked %%
|
| 88 |
-
File "/app/app.py", line 1090, in update_attribution_target_options
|
| 89 |
-
options.append({'label': f"{t['token']} ({t['probability']:.1%})", 'value': t['token']})
|
| 90 |
-
TypeError: unsupported format string passed to NoneType.__format__
|
| 91 |
-
-------------------------------------------------------
|
| 92 |
-
DEBUG extract_layer_data: Found 24 attention modules
|
| 93 |
-
Loading model: gpt2-medium
|
| 94 |
-
Loading weights: 0%| | 0/292 [00:00<?, ?it/s]
|
| 95 |
-
Loading weights: 51%|█████ | 149/292 [00:00<00:00, 1299.04it/s]
|
| 96 |
-
Loading weights: 100%|██████████| 292/292 [00:00<00:00, 1450.02it/s]
|
| 97 |
-
GPT2LMHeadModel LOAD REPORT from: gpt2-medium
|
| 98 |
-
Key | Status |
|
| 99 |
-
---------------+---------+-
|
| 100 |
-
lm_head.weight | MISSING |
|
| 101 |
-
|
| 102 |
-
Notes:
|
| 103 |
-
- MISSING :those params were newly initialized because missing from the checkpoint. Consider training on your downstream task.
|
| 104 |
-
-------------------------------------------------------
|
| 105 |
-
10.16.43.195 - - [19/Mar/2026 20:11:03] "POST /_dash-update-component HTTP/1.1" 200 -
|
| 106 |
-
[2026-03-19 20:11:03,238] ERROR in app: Exception on /_dash-update-component [POST]
|
| 107 |
-
Traceback (most recent call last):
|
| 108 |
-
File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1511, in wsgi_app
|
| 109 |
-
response = self.full_dispatch_request()
|
| 110 |
-
File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 919, in full_dispatch_request
|
| 111 |
-
rv = self.handle_user_exception(e)
|
| 112 |
-
File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 917, in full_dispatch_request
|
| 113 |
-
rv = self.dispatch_request()
|
| 114 |
-
File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 902, in dispatch_request
|
| 115 |
-
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
|
| 116 |
-
File "/usr/local/lib/python3.10/site-packages/dash/_get_app.py", line 17, in wrap
|
| 117 |
-
return ctx.run(func, self, *args, **kwargs)
|
| 118 |
-
File "/usr/local/lib/python3.10/site-packages/dash/dash.py", line 1600, in dispatch
|
| 119 |
-
response_data = ctx.run(partial_func)
|
| 120 |
-
File "/usr/local/lib/python3.10/site-packages/dash/_callback.py", line 720, in add_context
|
| 121 |
-
raise err
|
| 122 |
-
File "/usr/local/lib/python3.10/site-packages/dash/_callback.py", line 711, in add_context
|
| 123 |
-
output_value = _invoke_callback(func, *func_args, **func_kwargs) # type: ignore[reportArgumentType]
|
| 124 |
-
File "/usr/local/lib/python3.10/site-packages/dash/_callback.py", line 58, in _invoke_callback
|
| 125 |
-
return func(*args, **kwargs) # %% callback invoked %%
|
| 126 |
-
File "/app/app.py", line 1090, in update_attribution_target_options
|
| 127 |
-
options.append({'label': f"{t['token']} ({t['probability']:.1%})", 'value': t['token']})
|
| 128 |
-
TypeError: unsupported format string passed to NoneType.__format__
|
| 129 |
-
10.16.43.195 - - [19/Mar/2026 20:11:03] "POST /_dash-update-component HTTP/1.1" 500 -
|
| 130 |
-
10.16.43.195 - - [19/Mar/2026 20:11:03] "POST /_dash-update-component HTTP/1.1" 200 -
|
| 131 |
-
Traceback (most recent call last):
|
| 132 |
-
File "/app/utils/model_patterns.py", line 1337, in generate_bertviz_html
|
| 133 |
-
attention_weights = torch.tensor(attention_output[1]) # [batch, heads, seq, seq]
|
| 134 |
-
RuntimeError: Could not infer dtype of NoneType
|
| 135 |
-
Traceback (most recent call last):
|
| 136 |
-
File "/app/app.py", line 691, in update_pipeline_content
|
| 137 |
-
outputs.append(create_output_content(
|
| 138 |
-
File "/app/components/pipeline.py", line 1130, in create_output_content
|
| 139 |
-
text=[f"{p:.1%}" for p in probs], textposition='outside',
|
| 140 |
-
File "/app/components/pipeline.py", line 1130, in <listcomp>
|
| 141 |
-
text=[f"{p:.1%}" for p in probs], textposition='outside',
|
| 142 |
-
TypeError: unsupported format string passed to NoneType.__format__
|
| 143 |
-
-------------------------------------------------------
|
| 144 |
-
10.16.43.195 - - [19/Mar/2026 20:26:26] "POST /_dash-update-component HTTP/1.1" 200 -
|
| 145 |
-
DEBUG extract_layer_data: Found 24 attention modules
|
| 146 |
-
Warning: Could not compute logit lens for gpt_neox.layers.0: mixed dtype (CPU): expect parameter to have scalar type of Float
|
| 147 |
-
Warning: Could not compute token probabilities for gpt_neox.layers.0: mixed dtype (CPU): expect parameter to have scalar type of Float
|
| 148 |
-
Warning: Could not compute logit lens for gpt_neox.layers.1: mixed dtype (CPU): expect parameter to have scalar type of Float
|
| 149 |
-
Warning: Could not compute token probabilities for gpt_neox.layers.1: mixed dtype (CPU): expect parameter to have scalar type of Float
|
| 150 |
-
Warning: Could not compute logit lens for gpt_neox.layers.2: mixed dtype (CPU): expect parameter to have scalar type of Float
|
| 151 |
-
Warning: Could not compute token probabilities for gpt_neox.layers.2: mixed dtype (CPU): expect parameter to have scalar type of Float
|
| 152 |
-
-------------------------------------------------------
|
| 153 |
-
Warning: Could not compute logit lens for gpt_neox.layers.13: mixed dtype (CPU): expect parameter to have scalar type of Float
|
| 154 |
-
Warning: Could not compute token probabilities for gpt_neox.layers.13: mixed dtype (CPU): expect parameter to have scalar type of Float
|
| 155 |
-
Warning: Could not compute logit lens for gpt_neox.layers.14: Could not infer dtype of NoneType
|
| 156 |
-
Warning: Could not compute token probabilities for gpt_neox.layers.14: Could not infer dtype of NoneType
|
| 157 |
-
Warning: Could not compute logit lens for gpt_neox.layers.15: Could not infer dtype of NoneType
|
| 158 |
-
Warning: Could not compute token probabilities for gpt_neox.layers.15: Could not infer dtype of NoneType
|
| 159 |
-
Warning: Could not compute logit lens for gpt_neox.layers.16: Could not infer dtype of NoneType
|
| 160 |
-
Warning: Could not compute token probabilities for gpt_neox.layers.16: Could not infer dtype of NoneType
|
| 161 |
-
Warning: Could not compute logit lens for gpt_neox.layers.17: Could not infer dtype of NoneType
|
| 162 |
-
Warning: Could not compute token probabilities for gpt_neox.layers.17: Could not infer dtype of NoneType
|
| 163 |
-
-------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plans.md
CHANGED
|
@@ -1,16 +1,3 @@
|
|
| 1 |
-
|
| 2 |
-
-
|
| 3 |
-
|
| 4 |
-
Done:
|
| 5 |
-
- change attention to entire generated sequence
|
| 6 |
-
- change width of chatbot window
|
| 7 |
-
- add output token generation to attention, tokenization, etc
|
| 8 |
-
- output slider to look at each token (scrubber with top-5 at each position)
|
| 9 |
-
- experiment results side by side comparison
|
| 10 |
-
- output streaming for chatbot
|
| 11 |
-
- shorter, concise responses in system prompt
|
| 12 |
-
- add video links to glossary
|
| 13 |
-
- three blue one brown
|
| 14 |
-
- specs on what each attention head does
|
| 15 |
-
- generating with 1 output token doesn't show the "selected" beam, so users can't see the output from the model
|
| 16 |
-
- add head index numbers to color swatches in BertViz visualization graph
|
|
|
|
| 1 |
+
- make it more obvious that this is an experiment (pre-loaded things to ask)
|
| 2 |
+
- make sure chatbot explains simpler
|
| 3 |
+
- glossary button move
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
todo.md
DELETED
|
@@ -1,227 +0,0 @@
|
|
| 1 |
-
# Todo
|
| 2 |
-
|
| 3 |
-
## Completed: Test Suite Setup (Done)
|
| 4 |
-
- [x] Create `tests/` folder with `__init__.py` and `conftest.py` (shared fixtures)
|
| 5 |
-
- [x] Create `test_model_config.py` - 15 tests for model family lookups
|
| 6 |
-
- [x] Create `test_ablation_metrics.py` - 8 tests for KL divergence and probability deltas
|
| 7 |
-
- [x] Create `test_head_detection.py` - 20 tests for attention head categorization
|
| 8 |
-
- [x] Create `test_model_patterns.py` - 16 tests for merge_token_probabilities, safe_to_serializable
|
| 9 |
-
- [x] Create `test_token_attribution.py` - 11 tests for visualization data formatting
|
| 10 |
-
- [x] Verify all 73 tests pass with `pytest tests/ -v`
|
| 11 |
-
|
| 12 |
-
## Completed: Pipeline Explanation Refactor
|
| 13 |
-
|
| 14 |
-
### Phase 1: New Components (Done)
|
| 15 |
-
- [x] Create `components/pipeline.py` with 5 expandable stages
|
| 16 |
-
- [x] Create `utils/token_attribution.py` with Integrated Gradients
|
| 17 |
-
- [x] Create `components/investigation_panel.py` (ablation + attribution)
|
| 18 |
-
|
| 19 |
-
### Phase 2: Simplifications (Done)
|
| 20 |
-
- [x] Remove comparison UI from `model_selector.py`
|
| 21 |
-
- [x] Refactor `app.py`: wire pipeline, remove heatmap/comparison callbacks
|
| 22 |
-
|
| 23 |
-
### Phase 3: Cleanup (Done)
|
| 24 |
-
- [x] Delete `main_panel.py`
|
| 25 |
-
- [x] Delete `prompt_comparison.py`
|
| 26 |
-
- [x] Update `utils/__init__.py` exports
|
| 27 |
-
- [x] Add pipeline CSS styles to `assets/style.css`
|
| 28 |
-
|
| 29 |
-
## Completed: Pipeline Clarity Improvements (Agent A)
|
| 30 |
-
|
| 31 |
-
- [x] Rename "Max New Tokens:" to "Number of New Tokens:" in app.py
|
| 32 |
-
- [x] Rename "Beam Width:" to "Number of Generation Choices:" in app.py
|
| 33 |
-
- [x] Remove score display from generated sequences in app.py
|
| 34 |
-
- [x] Update glossary to clarify "Number of Generation Choices" relates to Beam Search
|
| 35 |
-
|
| 36 |
-
## Completed: Pipeline Clarity Improvements (Agent E)
|
| 37 |
-
|
| 38 |
-
- [x] Modified output display to show full prompt with predicted token highlighted
|
| 39 |
-
- [x] Fixed top-5 tokens hover to show "Token (X%)" format instead of long decimals
|
| 40 |
-
- [x] Added Plotly hovertemplate for cleaner hover formatting
|
| 41 |
-
|
| 42 |
-
## Completed: Pipeline Clarity Improvements (Agent C)
|
| 43 |
-
|
| 44 |
-
- [x] Add educational explanation for embedding stage (pre-learned lookup table concept)
|
| 45 |
-
- [x] Add educational explanation for MLP stage (knowledge storage during training)
|
| 46 |
-
- [x] Add educational explanation for attention stage (how to interpret BertViz visualization)
|
| 47 |
-
|
| 48 |
-
## Completed: Pipeline Clarity Improvements (Agent B)
|
| 49 |
-
|
| 50 |
-
- [x] Convert tokenization from horizontal three-column layout to vertical rows
|
| 51 |
-
- [x] Each token row shows: [token] → [ID] → [embedding placeholder]
|
| 52 |
-
- [x] Maintain existing color scheme and educational tooltips
|
| 53 |
-
- [x] Update CSS styles for .tokenization-rows and .token-row layout
|
| 54 |
-
- [x] Add responsive styles for mobile (stack on small screens)
|
| 55 |
-
|
| 56 |
-
## Completed: Pipeline Clarity Improvements (Agent D)
|
| 57 |
-
|
| 58 |
-
- [x] Switch generate_bertviz_html from model_view to head_view in model_patterns.py
|
| 59 |
-
- [x] Deprecate _get_top_attended_tokens function (remove usage in extract_layer_data)
|
| 60 |
-
- [x] Add generate_head_view_with_categories function for categorized attention heads
|
| 61 |
-
- [x] Add get_head_category_counts helper function for UI display
|
| 62 |
-
- [x] Run tests to verify no regressions (73 tests pass)
|
| 63 |
-
|
| 64 |
-
## Completed: Pipeline Clarity Improvements (Agent F - Analysis Scope)
|
| 65 |
-
|
| 66 |
-
- [x] Add session-original-prompt-store and session-selected-beam-store to app.py
|
| 67 |
-
- [x] Modify run_generation to analyze ORIGINAL PROMPT only (not generated beam)
|
| 68 |
-
- [x] Store beam generation results separately for post-experiment comparison
|
| 69 |
-
- [x] Update analyze_selected_sequence to store beam for comparison instead of re-analyzing
|
| 70 |
-
- [x] Update ablation experiment to show selected beam context in results
|
| 71 |
-
|
| 72 |
-
## Completed: Pipeline Clarity Improvements (Agent G - Integration & Attention UI)
|
| 73 |
-
|
| 74 |
-
- [x] Remove deprecated "Most attended tokens" section from attention stage
|
| 75 |
-
- [x] Wire head categorization into attention stage UI (shows category counts)
|
| 76 |
-
- [x] Add enhanced navigation instructions for BertViz head view
|
| 77 |
-
- [x] Verify all 73 tests pass
|
| 78 |
-
|
| 79 |
-
## Completed: UI/UX Fixes (5 Issues)
|
| 80 |
-
|
| 81 |
-
### Issue 1: "Select for Comparison" Button
|
| 82 |
-
- [x] Update store_selected_beam callback in app.py to update UI
|
| 83 |
-
- [x] Clear all other generated sequences when one is selected
|
| 84 |
-
- [x] Display selected sequence with "Selected for Comparison" badge
|
| 85 |
-
|
| 86 |
-
### Issue 2: Tokenization Vertical Layout
|
| 87 |
-
- [x] Modify create_tokenization_content in pipeline.py to use vertical layout
|
| 88 |
-
- [x] Each row displays: [token] → [ID] with header row
|
| 89 |
-
|
| 90 |
-
### Issue 3: Expandable Attention Categories
|
| 91 |
-
- [x] Convert category chips to expandable `<details>` elements in pipeline.py
|
| 92 |
-
- [x] Update app.py to pass full categorize_all_heads() data instead of counts
|
| 93 |
-
- [x] Show list of heads (L0-H3, L2-H5, etc.) when category is expanded
|
| 94 |
-
|
| 95 |
-
### Issue 4: BertViz Navigation Instructions
|
| 96 |
-
- [x] Add single-click explanation: selects/deselects that head
|
| 97 |
-
- [x] Add double-click explanation: selects only that head (deselects others)
|
| 98 |
-
|
| 99 |
-
### Issue 5: Multi-Layer Ablation Head Selection
|
| 100 |
-
- [x] Change ablation-selected-heads store to hold [{layer, head}, ...] objects
|
| 101 |
-
- [x] Add create_selected_heads_display function in investigation_panel.py
|
| 102 |
-
- [x] Show selected heads as chips with "x" buttons to remove
|
| 103 |
-
- [x] Update head buttons to show visual selection state per layer
|
| 104 |
-
- [x] Preserve selections across layer dropdown changes
|
| 105 |
-
- [x] Update run_ablation_experiment to handle multi-layer ablation
|
| 106 |
-
- [x] Verify all 73 tests pass
|
| 107 |
-
|
| 108 |
-
## Completed: Fix Multi-Layer Ablation Bug
|
| 109 |
-
|
| 110 |
-
- [x] Create `execute_forward_pass_with_multi_layer_head_ablation` in model_patterns.py
|
| 111 |
-
- [x] Export new function in utils/__init__.py
|
| 112 |
-
- [x] Replace per-layer ablation loop in app.py with single call to new function
|
| 113 |
-
- [x] Add 5 tests for multi-layer ablation in test_model_patterns.py
|
| 114 |
-
- [x] Verify all 78 tests pass
|
| 115 |
-
|
| 116 |
-
## Completed: Codebase Cleanup
|
| 117 |
-
|
| 118 |
-
- [x] Delete unused file: `components/tokenization_panel.py` (302 lines, 6 functions)
|
| 119 |
-
- [x] Remove 6 unused imports from `app.py`
|
| 120 |
-
- [x] Remove deprecated `_get_top_attended_tokens()` function from model_patterns.py
|
| 121 |
-
- [x] Remove `top_attended_tokens` field from extract_layer_data() return values
|
| 122 |
-
- [x] Remove unused `create_stage_summary()` function from pipeline.py
|
| 123 |
-
- [x] Remove 7 unused utility functions from utils/:
|
| 124 |
-
- `get_check_token_probabilities`
|
| 125 |
-
- `execute_forward_pass_with_layer_ablation`
|
| 126 |
-
- `generate_category_bertviz_html`
|
| 127 |
-
- `generate_head_view_with_categories`
|
| 128 |
-
- `compute_sequence_trajectory`
|
| 129 |
-
- `compute_layer_wise_summaries`
|
| 130 |
-
- `compute_position_layer_matrix`
|
| 131 |
-
- [x] Update `utils/__init__.py` exports
|
| 132 |
-
- [x] Update README.md to remove reference to deleted file
|
| 133 |
-
|
| 134 |
-
## Completed: AI Chatbot Integration
|
| 135 |
-
|
| 136 |
-
- [x] Create `rag_docs/` folder with placeholder README for RAG documents
|
| 137 |
-
- [x] Create `utils/gemini_client.py` with Gemini API wrapper (generate + embed)
|
| 138 |
-
- [x] Create `utils/rag_utils.py` with document loading, chunking, and retrieval
|
| 139 |
-
- [x] Create `components/chatbot.py` with UI components (icon, window, messages)
|
| 140 |
-
- [x] Add chatbot CSS to `assets/style.css` (floating button, chat window, message bubbles)
|
| 141 |
-
- [x] Modify `app.py` to add chat layout and callbacks
|
| 142 |
-
- [x] Add `google-generativeai` to `requirements.txt`
|
| 143 |
-
- [x] Test end-to-end: toggle, message send, context awareness
|
| 144 |
-
- [x] Verify all 81 tests pass
|
| 145 |
-
|
| 146 |
-
## Completed: Hugging Face Deployment Prep
|
| 147 |
-
|
| 148 |
-
- [x] Create `.gitignore` to exclude `.env`, `__pycache__/`, etc.
|
| 149 |
-
- [x] Add `load_dotenv()` to `app.py` for local development
|
| 150 |
-
- [x] Create `tests/test_gemini_connection.py` to verify API key connectivity
|
| 151 |
-
- [x] Tests verify: API key is set, can list models, flash model available
|
| 152 |
-
- Note: On Hugging Face Spaces, set `GEMINI_API_KEY` in Repository Secrets
|
| 153 |
-
|
| 154 |
-
## Completed: Migrate to New Google GenAI SDK (Superseded)
|
| 155 |
-
|
| 156 |
-
- [x] Update `requirements.txt`: `google-generativeai` → `google-genai>=1.0.0`
|
| 157 |
-
- [x] Rewrite `utils/gemini_client.py` using new centralized Client architecture
|
| 158 |
-
- [x] All 4 connection tests pass
|
| 159 |
-
- [x] Verified: embeddings work (3072 dimensions), chat generation works
|
| 160 |
-
|
| 161 |
-
## Completed: Migrate from Gemini to OpenRouter
|
| 162 |
-
|
| 163 |
-
- [x] Create `utils/openrouter_client.py` with OpenAI-compatible API
|
| 164 |
-
- Global model config: `DEFAULT_CHAT_MODEL` and `DEFAULT_EMBEDDING_MODEL`
|
| 165 |
-
- Chat via: `POST /api/v1/chat/completions`
|
| 166 |
-
- Embeddings via: `POST /api/v1/embeddings`
|
| 167 |
-
- [x] Update `utils/rag_utils.py` imports to use openrouter_client
|
| 168 |
-
- [x] Update `app.py` imports to use openrouter_client
|
| 169 |
-
- [x] Create `tests/test_openrouter_connection.py` for API connectivity tests
|
| 170 |
-
- [x] Delete old `utils/gemini_client.py` and `tests/test_gemini_connection.py`
|
| 171 |
-
- [x] Update `requirements.txt`: remove `google-genai`, add `requests>=2.28.0`
|
| 172 |
-
- [x] Environment variable: `GEMINI_API_KEY` → `OPENROUTER_API_KEY`
|
| 173 |
-
|
| 174 |
-
## Completed: Switch to Paid OpenRouter Models (Cost-Optimized)
|
| 175 |
-
|
| 176 |
-
- [x] Evaluate OpenRouter models for chatbot use case (cost vs quality)
|
| 177 |
-
- [x] Switch chat model: `google/gemini-2.5-flash-lite`
|
| 178 |
-
- $0.10/$0.40 per 1M tokens (input/output)
|
| 179 |
-
- 1M context window, 318 tok/s, multimodal
|
| 180 |
-
- [x] Switch embedding model: `openai/text-embedding-3-small`
|
| 181 |
-
- $0.02 per 1M tokens
|
| 182 |
-
- 1536 dimensions, high quality
|
| 183 |
-
- [x] Remove local `sentence-transformers` dependency (simpler, no TF conflicts)
|
| 184 |
-
- [x] Estimated cost: ~$1.50/month for moderate usage
|
| 185 |
-
|
| 186 |
-
## Completed: Enhance RAG Documents for Chatbot
|
| 187 |
-
|
| 188 |
-
- [x] Category 1: 8 general LLM/Transformer knowledge files (what_is_an_llm.md through key_terminology.md)
|
| 189 |
-
- [x] Category 2: 7 dashboard component documentation files (dashboard_overview.md through model_selector_guide.md)
|
| 190 |
-
- [x] Category 3: 3 model-specific documentation files (gpt2_overview.md, llama_overview.md, opt_overview.md)
|
| 191 |
-
- [x] Category 4: 6 step-by-step guided experiment files (experiment_first_analysis.md through experiment_beam_search.md)
|
| 192 |
-
- [x] Category 5: 6 interpretation/troubleshooting/research files (interpreting_*.md, troubleshooting_and_faq.md, recommended_starting_points.md, mechanistic_interpretability_intro.md)
|
| 193 |
-
- [x] Delete embeddings_cache.json, update rag_docs/README.md with full inventory
|
| 194 |
-
- [x] Update todo.md and conductor docs
|
| 195 |
-
- Total: 30 RAG documents covering transformer concepts, dashboard usage, guided experiments, interpretation, troubleshooting, and research context
|
| 196 |
-
|
| 197 |
-
## Completed: Resizable Chat Window
|
| 198 |
-
|
| 199 |
-
- [x] Add drag handle div to left edge of chat window in chatbot.py
|
| 200 |
-
- [x] Add CSS for `.chat-resize-handle` (cursor, hover highlight) in style.css
|
| 201 |
-
- [x] Add `assets/chat_resize.js` for mousedown/mousemove/mouseup drag logic
|
| 202 |
-
- Default size unchanged (25vw, 320px–450px); drag overrides max-width up to 80vw
|
| 203 |
-
|
| 204 |
-
## Completed: Full-Sequence Attention Visualization
|
| 205 |
-
|
| 206 |
-
- [x] Modified `run_generation()` in app.py: for single-token generation, run forward pass on full beam text (prompt + generated token) instead of prompt only
|
| 207 |
-
- [x] Enhanced `store_selected_beam()` in app.py: added `session-activation-store` output and `session-activation-store` State; re-runs `execute_forward_pass()` on selected beam's full text when user picks a beam
|
| 208 |
-
- [x] Added 5 tests in `test_model_patterns.py` (`TestFullSequenceAttentionData`) verifying attention matrix dimensions match full sequence length
|
| 209 |
-
- Attention visualization now covers the entire chosen output (input + generated tokens), not just the input prompt
|
| 210 |
-
- No changes needed in `model_patterns.py`, `beam_search.py`, `pipeline.py`, or `head_detection.py`
|
| 211 |
-
|
| 212 |
-
## Completed: Output Token Scrubber
|
| 213 |
-
|
| 214 |
-
- [x] Add `compute_per_position_top5()` to `utils/model_patterns.py` — extracts top-5 next-token probabilities at each generated-token position from a single forward pass
|
| 215 |
-
- [x] Add `original_prompt` parameter to `execute_forward_pass()` — when provided, computes per-position top-5 data and stores in activation_data
|
| 216 |
-
- [x] Export `compute_per_position_top5` in `utils/__init__.py`
|
| 217 |
-
- [x] Update `run_generation()` in app.py — passes `original_prompt=prompt` for single-token generation
|
| 218 |
-
- [x] Update `store_selected_beam()` in app.py — reads original prompt from session store and passes to forward pass
|
| 219 |
-
- [x] Rewrite `create_output_content()` in `components/pipeline.py` — scrubber mode with `dcc.Slider`, token display, and top-5 chart; falls back to static mode when no per-position data
|
| 220 |
-
- [x] Add `_build_token_display()` and `_build_top5_chart()` helpers in pipeline.py
|
| 221 |
-
- [x] Add `update_output_scrubber()` callback in app.py — responds to slider changes, updates token highlight and chart
|
| 222 |
-
- [x] Update `update_pipeline_content()` in app.py — extracts per-position data and passes to output content
|
| 223 |
-
- [x] Add 10 tests for `compute_per_position_top5` in `test_model_patterns.py`
|
| 224 |
-
- [x] Fix `conftest.py` to set `USE_TF=0` for test import compatibility
|
| 225 |
-
- [x] All 100 tests pass
|
| 226 |
-
- Scrubber shows prompt context (gray) + highlighted token (cyan) + top-5 bar chart at each slider position
|
| 227 |
-
- Pre-beam-selection falls back to static output display; scrubber activates after beam selection or single-token generation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|