Spaces:
Sleeping
Sleeping
Commit ·
2f024ca
1
Parent(s): d075209
Improved rules and added claude.md
Browse files- .agents/rules/agent-workflow.md +10 -7
- .claude/commands/update-memory.md +13 -0
- .cursor/rules/AGENTS.md +9 -6
- CLAUDE.md +60 -0
- RESEARCH-jargon-reduction.md +78 -0
- spec_attention_color_matching.md +0 -199
.agents/rules/agent-workflow.md
CHANGED
|
@@ -31,9 +31,9 @@ Interactive Dash app for exploring LLM internals through visualization and exper
|
|
| 31 |
## Data Files
|
| 32 |
| File | Path | Purpose |
|
| 33 |
|------|------|---------|
|
| 34 |
-
| Sessions | `.context/data/sessions.md` | Running work log
|
| 35 |
-
| Decisions | `.context/data/decisions.md` | Decision records with reasoning
|
| 36 |
-
| Lessons | `.context/data/lessons.md` | Hard-won knowledge and past mistakes
|
| 37 |
|
| 38 |
## Memory Maintenance
|
| 39 |
|
|
@@ -49,13 +49,16 @@ Always look for opportunities to update the memory system:
|
|
| 49 |
3. Never update memory mid-task without mentioning it
|
| 50 |
|
| 51 |
**Rules**:
|
| 52 |
-
- Data files are append-
|
| 53 |
-
-
|
| 54 |
-
-
|
|
|
|
|
|
|
|
|
|
| 55 |
|
| 56 |
## Preferences
|
| 57 |
- Don't ask permission for changes that fall within an approved plan — just execute
|
| 58 |
- Commit normal changes to main; feature branches for major components/refactors. Never merge branches.
|
| 59 |
- Keep `todo.md` and `plans.md` current before/after changes. Tasks should be atomic.
|
| 60 |
- When in doubt, research options and make a minimal reasonable choice, noting it in `todo.md`
|
| 61 |
-
- Explain manual tests clearly — what to look for, expected behavior, where to check
|
|
|
|
| 31 |
## Data Files
|
| 32 |
| File | Path | Purpose |
|
| 33 |
|------|------|---------|
|
| 34 |
+
| Sessions | `.context/data/sessions.md` | Running work log |
|
| 35 |
+
| Decisions | `.context/data/decisions.md` | Decision records with reasoning |
|
| 36 |
+
| Lessons | `.context/data/lessons.md` | Hard-won knowledge and past mistakes |
|
| 37 |
|
| 38 |
## Memory Maintenance
|
| 39 |
|
|
|
|
| 49 |
3. Never update memory mid-task without mentioning it
|
| 50 |
|
| 51 |
**Rules**:
|
| 52 |
+
- Data files are append-first with compression — new entries are appended, but older entries may be compressed when:
|
| 53 |
+
- **Conflicting information**: A newer entry supersedes an older one (e.g., a feature is replaced or deprecated). Compress the old entry into a brief note that preserves the history without full detail.
|
| 54 |
+
- **Excessive size**: When a file exceeds ~30 entries, summarize the oldest ~20 into a dense "Archive" block at the top (a few lines), retaining the most recent ~10 as full entries. This keeps long-term memory without bloating context.
|
| 55 |
+
- When compressing, never delete history entirely — always leave a condensed trace so the evolution of the project is visible.
|
| 56 |
+
- Modules can be edited but changes should be targeted, not full rewrites.
|
| 57 |
+
- After substantive work sessions, append a summary to `.context/data/sessions.md`.
|
| 58 |
|
| 59 |
## Preferences
|
| 60 |
- Don't ask permission for changes that fall within an approved plan — just execute
|
| 61 |
- Commit normal changes to main; feature branches for major components/refactors. Never merge branches.
|
| 62 |
- Keep `todo.md` and `plans.md` current before/after changes. Tasks should be atomic.
|
| 63 |
- When in doubt, research options and make a minimal reasonable choice, noting it in `todo.md`
|
| 64 |
+
- Explain manual tests clearly — what to look for, expected behavior, where to check
|
.claude/commands/update-memory.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
This session is wrapping up. Review what was accomplished and update the memory system per the CLAUDE.md instructions.
|
| 2 |
+
|
| 3 |
+
Steps:
|
| 4 |
+
1. Run `git diff HEAD~3` and `git log --oneline -10` to see recent changes and commits from this session.
|
| 5 |
+
2. Read the current state of the memory/data files:
|
| 6 |
+
- `.context/data/sessions.md` — append a session summary
|
| 7 |
+
- `.context/data/decisions.md` — append any decisions made with reasoning
|
| 8 |
+
- `.context/data/lessons.md` — append any hard-won knowledge or mistakes caught
|
| 9 |
+
3. Check if any `.context/modules/` files need targeted updates based on what changed (new patterns, conventions, architecture shifts).
|
| 10 |
+
4. For each proposed update: state which file changes and what the change is, then wait for approval before writing.
|
| 11 |
+
5. Update `todo.md` and `plans.md` if tasks were completed or new ones emerged.
|
| 12 |
+
|
| 13 |
+
Additional context from the user (if any): $ARGUMENTS
|
.cursor/rules/AGENTS.md
CHANGED
|
@@ -38,9 +38,9 @@ Interactive Dash app for exploring LLM internals through visualization and exper
|
|
| 38 |
## Data Files
|
| 39 |
| File | Path | Purpose |
|
| 40 |
|------|------|---------|
|
| 41 |
-
| Sessions | `.context/data/sessions.md` | Running work log
|
| 42 |
-
| Decisions | `.context/data/decisions.md` | Decision records with reasoning
|
| 43 |
-
| Lessons | `.context/data/lessons.md` | Hard-won knowledge and past mistakes
|
| 44 |
|
| 45 |
## Memory Maintenance
|
| 46 |
|
|
@@ -56,9 +56,12 @@ Always look for opportunities to update the memory system:
|
|
| 56 |
3. Never update memory mid-task without mentioning it
|
| 57 |
|
| 58 |
**Rules**:
|
| 59 |
-
- Data files are append-
|
| 60 |
-
-
|
| 61 |
-
-
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
## Preferences
|
| 64 |
- Don't ask permission for changes that fall within an approved plan — just execute
|
|
|
|
| 38 |
## Data Files
|
| 39 |
| File | Path | Purpose |
|
| 40 |
|------|------|---------|
|
| 41 |
+
| Sessions | `.context/data/sessions.md` | Running work log |
|
| 42 |
+
| Decisions | `.context/data/decisions.md` | Decision records with reasoning |
|
| 43 |
+
| Lessons | `.context/data/lessons.md` | Hard-won knowledge and past mistakes |
|
| 44 |
|
| 45 |
## Memory Maintenance
|
| 46 |
|
|
|
|
| 56 |
3. Never update memory mid-task without mentioning it
|
| 57 |
|
| 58 |
**Rules**:
|
| 59 |
+
- Data files are append-first with compression — new entries are appended, but older entries may be compressed when:
|
| 60 |
+
- **Conflicting information**: A newer entry supersedes an older one (e.g., a feature is replaced or deprecated). Compress the old entry into a brief note that preserves the history without full detail.
|
| 61 |
+
- **Excessive size**: When a file exceeds ~30 entries, summarize the oldest ~20 into a dense "Archive" block at the top (a few lines), retaining the most recent ~10 as full entries. This keeps long-term memory without bloating context.
|
| 62 |
+
- When compressing, never delete history entirely — always leave a condensed trace so the evolution of the project is visible.
|
| 63 |
+
- Modules can be edited but changes should be targeted, not full rewrites.
|
| 64 |
+
- After substantive work sessions, append a summary to `.context/data/sessions.md`.
|
| 65 |
|
| 66 |
## Preferences
|
| 67 |
- Don't ask permission for changes that fall within an approved plan — just execute
|
CLAUDE.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Transformer Explanation Dashboard
|
| 2 |
+
Interactive Dash app for exploring LLM internals through visualization and experimentation. Built with Python, Dash, PyTorch, HF Transformers, Bertviz, pyvene.
|
| 3 |
+
|
| 4 |
+
## Critical Rules
|
| 5 |
+
- **Dead code cleanup is mandatory during refactors.** Sweep for orphaned code from deprecated/deleted components every time.
|
| 6 |
+
- **Conceptual understanding over math rigor.** Skip complex derivations; focus on motivation and intuition that builds correct mental models.
|
| 7 |
+
- **Sanity check every change:** (1) Does this help someone learn about transformers? (2) Is the simplification accurate enough? (3) Am I in a rabbit hole?
|
| 8 |
+
- **TDD for backend logic.** Write failing tests first for anything in `utils/`. Skip tests for UI-only changes. Run `pytest` after every change; iterate until green.
|
| 9 |
+
- **Don't run the app.** Describe manual verification steps; the user will test themselves.
|
| 10 |
+
- **Surgical edits over rewrites.** Reuse existing files. Only create new modules when existing ones can't be extended.
|
| 11 |
+
- **No new dependencies** unless strictly necessary.
|
| 12 |
+
- **Push back on bad ideas.** Think through problems fully. Don't be a yes-man — challenge flawed approaches.
|
| 13 |
+
- **Components = layout only** (no ML logic). **Utils = computation only** (no Dash imports). **app.py = glue.**
|
| 14 |
+
- **Dash callbacks must stay responsive.** No heavy sync work in callbacks without feedback indicators.
|
| 15 |
+
- Don't reformat unrelated code or alter indentation styles.
|
| 16 |
+
- Check for zombie processes before debugging server errors.
|
| 17 |
+
|
| 18 |
+
## Module Map
|
| 19 |
+
| Module | Path | Load when |
|
| 20 |
+
|--------|------|-----------|
|
| 21 |
+
| Product | `.context/modules/product.md` | Understanding vision, features, brand voice, visual identity, UX patterns |
|
| 22 |
+
| Architecture | `.context/modules/architecture.md` | Understanding system structure, data flow, or component boundaries |
|
| 23 |
+
| Conventions | `.context/modules/conventions.md` | Writing or reviewing code style, naming, commits, dead code cleanup |
|
| 24 |
+
| Education | `.context/modules/education.md` | Creating or editing educational content, visualizations, explanations |
|
| 25 |
+
| Testing | `.context/modules/testing.md` | Writing tests, running pytest, TDD workflow |
|
| 26 |
+
|
| 27 |
+
## Data Files
|
| 28 |
+
| File | Path | Purpose |
|
| 29 |
+
|------|------|---------|
|
| 30 |
+
| Sessions | `.context/data/sessions.md` | Running work log |
|
| 31 |
+
| Decisions | `.context/data/decisions.md` | Decision records with reasoning |
|
| 32 |
+
| Lessons | `.context/data/lessons.md` | Hard-won knowledge and past mistakes |
|
| 33 |
+
|
| 34 |
+
## Memory Maintenance
|
| 35 |
+
|
| 36 |
+
Always look for opportunities to update the memory system:
|
| 37 |
+
- **New patterns**: "We've been doing X consistently — should I add it to conventions?"
|
| 38 |
+
- **Decisions made**: "We decided Y — should I record this in decisions.md?"
|
| 39 |
+
- **Mistakes caught**: "This went wrong because Z — should I add it to lessons.md?"
|
| 40 |
+
- **Scope changes**: "The project now includes W — should I create a new module?"
|
| 41 |
+
|
| 42 |
+
**Before any memory update**:
|
| 43 |
+
1. State which file(s) would change and what the change would be
|
| 44 |
+
2. Wait for approval
|
| 45 |
+
3. Never update memory mid-task without mentioning it
|
| 46 |
+
|
| 47 |
+
**Rules**:
|
| 48 |
+
- Data files are append-first with compression — new entries are appended, but older entries may be compressed when:
|
| 49 |
+
- **Conflicting information**: A newer entry supersedes an older one (e.g., a feature is replaced or deprecated). Compress the old entry into a brief note that preserves the history without full detail.
|
| 50 |
+
- **Excessive size**: When a file exceeds ~30 entries, summarize the oldest ~20 into a dense "Archive" block at the top (a few lines), retaining the most recent ~10 as full entries. This keeps long-term memory without bloating context.
|
| 51 |
+
- When compressing, never delete history entirely — always leave a condensed trace so the evolution of the project is visible.
|
| 52 |
+
- Modules can be edited but changes should be targeted, not full rewrites.
|
| 53 |
+
- After substantive work sessions, append a summary to `.context/data/sessions.md`.
|
| 54 |
+
|
| 55 |
+
## Preferences
|
| 56 |
+
- Don't ask permission for changes that fall within an approved plan — just execute
|
| 57 |
+
- Commit normal changes to main; feature branches for major components/refactors. Never merge branches.
|
| 58 |
+
- Keep `todo.md` and `plans.md` current before/after changes. Tasks should be atomic.
|
| 59 |
+
- When in doubt, research options and make a minimal reasonable choice, noting it in `todo.md`
|
| 60 |
+
- Explain manual tests clearly — what to look for, expected behavior, where to check
|
RESEARCH-jargon-reduction.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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.
|
spec_attention_color_matching.md
DELETED
|
@@ -1,199 +0,0 @@
|
|
| 1 |
-
# SPEC: Head Color Swatches in LLMVis
|
| 2 |
-
**Status:** Ready for implementation
|
| 3 |
-
**Date:** 2026-03-05
|
| 4 |
-
|
| 5 |
-
---
|
| 6 |
-
|
| 7 |
-
## Goal
|
| 8 |
-
|
| 9 |
-
Add colored square swatches next to attention head labels in:
|
| 10 |
-
1. The attention head category panels (pipeline.py)
|
| 11 |
-
2. The ablation panel's selected head chips (ablation_panel.py)
|
| 12 |
-
|
| 13 |
-
The colors must match what BertViz's head_view renders for each head index, so students can visually correlate "L4-H11 [magenta square]" in the panel with the magenta checkbox in the BertViz visualization.
|
| 14 |
-
|
| 15 |
-
---
|
| 16 |
-
|
| 17 |
-
## Core Insight
|
| 18 |
-
|
| 19 |
-
BertViz's `head_view(..., html_action='return')` returns the full JS inlined as a string. We can patch `d3.schemeCategory10` → a custom 24-color palette at generation time. The swatches in our UI then reference the same palette — perfect correlation, zero color collisions.
|
| 20 |
-
|
| 21 |
-
**Why not schemeCategory10?** GPT-2 (default model) has 12 heads/layer. schemeCategory10 cycles every 10, so H10 = H0 (both blue) and H11 = H1 (both orange). That defeats the purpose.
|
| 22 |
-
|
| 23 |
-
---
|
| 24 |
-
|
| 25 |
-
## The Palette
|
| 26 |
-
|
| 27 |
-
Dark24 (Plotly) with two near-invisible entries replaced:
|
| 28 |
-
|
| 29 |
-
```python
|
| 30 |
-
BERTVIZ_HEAD_COLORS = [
|
| 31 |
-
'#2E91E5', # H0 - blue
|
| 32 |
-
'#E15F99', # H1 - pink-red
|
| 33 |
-
'#1CA71C', # H2 - green
|
| 34 |
-
'#FB0D0D', # H3 - red
|
| 35 |
-
'#DA16FF', # H4 - purple
|
| 36 |
-
'#00B4D8', # H5 - cyan (was #222A2A near-black → swapped)
|
| 37 |
-
'#B68100', # H6 - gold
|
| 38 |
-
'#06D6A0', # H7 - teal (was #750D86 very dark purple → swapped)
|
| 39 |
-
'#EB663B', # H8 - orange
|
| 40 |
-
'#511CFB', # H9 - indigo
|
| 41 |
-
'#00A08B', # H10 - dark teal
|
| 42 |
-
'#FB00D1', # H11 - magenta
|
| 43 |
-
'#FC0080', # H12 - hot pink
|
| 44 |
-
'#B2828D', # H13 - mauve
|
| 45 |
-
'#6C7C32', # H14 - olive
|
| 46 |
-
'#778AAE', # H15 - slate blue
|
| 47 |
-
]
|
| 48 |
-
```
|
| 49 |
-
|
| 50 |
-
16 colors covers all supported models (max 16 heads/layer: gpt2-medium, pythia-410m, Qwen2.5-0.5B).
|
| 51 |
-
|
| 52 |
-
---
|
| 53 |
-
|
| 54 |
-
## Files to Change
|
| 55 |
-
|
| 56 |
-
### 1. New file: `utils/colors.py`
|
| 57 |
-
Define `BERTVIZ_HEAD_COLORS` here as the single source of truth. Import from here everywhere else.
|
| 58 |
-
|
| 59 |
-
```python
|
| 60 |
-
"""Shared color constants for LLMVis."""
|
| 61 |
-
|
| 62 |
-
# 16-color palette for BertViz head_view.
|
| 63 |
-
# Patched into BertViz at generation time (model_patterns.py) and mirrored
|
| 64 |
-
# in UI swatches (pipeline.py, ablation_panel.py) for visual correlation.
|
| 65 |
-
# Based on Plotly Dark24, with H5 and H7 replaced for legibility.
|
| 66 |
-
BERTVIZ_HEAD_COLORS = [
|
| 67 |
-
'#2E91E5', # H0 - blue
|
| 68 |
-
'#E15F99', # H1 - pink-red
|
| 69 |
-
'#1CA71C', # H2 - green
|
| 70 |
-
'#FB0D0D', # H3 - red
|
| 71 |
-
'#DA16FF', # H4 - purple
|
| 72 |
-
'#00B4D8', # H5 - cyan
|
| 73 |
-
'#B68100', # H6 - gold
|
| 74 |
-
'#06D6A0', # H7 - teal
|
| 75 |
-
'#EB663B', # H8 - orange
|
| 76 |
-
'#511CFB', # H9 - indigo
|
| 77 |
-
'#00A08B', # H10 - dark teal
|
| 78 |
-
'#FB00D1', # H11 - magenta
|
| 79 |
-
'#FC0080', # H12 - hot pink
|
| 80 |
-
'#B2828D', # H13 - mauve
|
| 81 |
-
'#6C7C32', # H14 - olive
|
| 82 |
-
'#778AAE', # H15 - slate blue
|
| 83 |
-
]
|
| 84 |
-
|
| 85 |
-
def head_color(head_index: int) -> str:
|
| 86 |
-
"""Return the swatch color for a given head index."""
|
| 87 |
-
return BERTVIZ_HEAD_COLORS[head_index % len(BERTVIZ_HEAD_COLORS)]
|
| 88 |
-
```
|
| 89 |
-
|
| 90 |
-
---
|
| 91 |
-
|
| 92 |
-
### 2. `utils/model_patterns.py` — `generate_bertviz_html()`
|
| 93 |
-
|
| 94 |
-
After the `head_view(...)` call, patch the returned HTML string to replace BertViz's default color scheme with ours. Both the primary and fallback d3 lines must be replaced.
|
| 95 |
-
|
| 96 |
-
**Locate:** the `else:` block in `generate_bertviz_html()` (around line 1414):
|
| 97 |
-
```python
|
| 98 |
-
html_result = head_view(attentions, tokens, html_action='return')
|
| 99 |
-
return html_result.data if hasattr(html_result, 'data') else str(html_result)
|
| 100 |
-
```
|
| 101 |
-
|
| 102 |
-
**Replace with:**
|
| 103 |
-
```python
|
| 104 |
-
from utils.colors import BERTVIZ_HEAD_COLORS
|
| 105 |
-
html_result = head_view(attentions, tokens, html_action='return')
|
| 106 |
-
html_str = html_result.data if hasattr(html_result, 'data') else str(html_result)
|
| 107 |
-
|
| 108 |
-
# Patch BertViz color scheme to match our swatch palette (no collisions for ≤16 heads)
|
| 109 |
-
_colors_js = repr(BERTVIZ_HEAD_COLORS).replace("'", '"') # JSON-safe array literal
|
| 110 |
-
_patch = f"headColors = d3.scaleOrdinal({_colors_js});"
|
| 111 |
-
html_str = html_str.replace(
|
| 112 |
-
'headColors = d3.scaleOrdinal(d3.schemeCategory10);',
|
| 113 |
-
_patch
|
| 114 |
-
)
|
| 115 |
-
html_str = html_str.replace(
|
| 116 |
-
'headColors = d3.scale.category10();',
|
| 117 |
-
_patch
|
| 118 |
-
)
|
| 119 |
-
return html_str
|
| 120 |
-
```
|
| 121 |
-
|
| 122 |
-
---
|
| 123 |
-
|
| 124 |
-
### 3. `components/pipeline.py` — `create_attention_content()`
|
| 125 |
-
|
| 126 |
-
Import `head_color` from `utils.colors` at the top of the file.
|
| 127 |
-
|
| 128 |
-
In the `head_items` loop (around line 536), the head label is currently:
|
| 129 |
-
```python
|
| 130 |
-
html.Span(label, style={
|
| 131 |
-
'fontFamily': 'monospace', 'fontSize': '12px', 'fontWeight': '500',
|
| 132 |
-
'minWidth': '60px', 'color': '#495057' if is_active else '#aaa',
|
| 133 |
-
}, title=f"See Layer {head_info['layer']}, Head {head_info['head']} in the visualization below"),
|
| 134 |
-
```
|
| 135 |
-
|
| 136 |
-
**Replace with:**
|
| 137 |
-
```python
|
| 138 |
-
html.Span([
|
| 139 |
-
html.Span("■ ", style={
|
| 140 |
-
'color': head_color(head_info['head']),
|
| 141 |
-
'fontSize': '14px',
|
| 142 |
-
}),
|
| 143 |
-
label
|
| 144 |
-
], style={
|
| 145 |
-
'fontFamily': 'monospace', 'fontSize': '12px', 'fontWeight': '500',
|
| 146 |
-
'minWidth': '60px', 'color': '#495057' if is_active else '#aaa',
|
| 147 |
-
'display': 'inline-flex', 'alignItems': 'center',
|
| 148 |
-
}, title=f"See Layer {head_info['layer']}, Head {head_info['head']} in the visualization below"),
|
| 149 |
-
```
|
| 150 |
-
|
| 151 |
-
Note: The swatch always renders at full color even for inactive heads — the parent `html.Div` already applies `opacity: 0.5` for inactive heads, which will naturally dim the swatch too. No special handling needed.
|
| 152 |
-
|
| 153 |
-
---
|
| 154 |
-
|
| 155 |
-
### 4. `components/ablation_panel.py` — `create_selected_heads_display()`
|
| 156 |
-
|
| 157 |
-
Import `head_color` from `utils.colors` at the top of the file.
|
| 158 |
-
|
| 159 |
-
In the chips loop, the label is currently:
|
| 160 |
-
```python
|
| 161 |
-
label = f"L{layer}-H{head}"
|
| 162 |
-
|
| 163 |
-
chips.append(
|
| 164 |
-
html.Span([
|
| 165 |
-
html.Span(label, style={'marginRight': '6px'}),
|
| 166 |
-
...
|
| 167 |
-
], ...)
|
| 168 |
-
)
|
| 169 |
-
```
|
| 170 |
-
|
| 171 |
-
**Replace** the `html.Span(label, ...)` with:
|
| 172 |
-
```python
|
| 173 |
-
html.Span([
|
| 174 |
-
html.Span("■ ", style={
|
| 175 |
-
'color': head_color(head),
|
| 176 |
-
'fontSize': '14px',
|
| 177 |
-
'marginRight': '2px',
|
| 178 |
-
}),
|
| 179 |
-
html.Span(label, style={'marginRight': '6px'}),
|
| 180 |
-
], style={'display': 'inline-flex', 'alignItems': 'center'}),
|
| 181 |
-
```
|
| 182 |
-
|
| 183 |
-
---
|
| 184 |
-
|
| 185 |
-
## Exit Criteria
|
| 186 |
-
|
| 187 |
-
- [ ] BertViz head_view renders with the new palette — H0 is blue, H10 is dark teal, H11 is magenta (visually distinct from H1)
|
| 188 |
-
- [ ] Every head label in the attention category panels shows a colored square matching BertViz
|
| 189 |
-
- [ ] Every ablation chip shows a matching colored square
|
| 190 |
-
- [ ] Spot checks: `L0-H0` = `#2E91E5`, `L4-H10` = `#00A08B`, `L4-H11` = `#FB00D1`
|
| 191 |
-
- [ ] `BERTVIZ_HEAD_COLORS` / `head_color()` defined in exactly one place (`utils/colors.py`), imported everywhere else
|
| 192 |
-
- [ ] No functional changes to callbacks, stores, or any other logic
|
| 193 |
-
- [ ] Existing tests still pass
|
| 194 |
-
|
| 195 |
-
## Non-Goals
|
| 196 |
-
- No changes to model_view (not used in this app)
|
| 197 |
-
- No hover/interactive effects on swatches
|
| 198 |
-
- No changes to per-category color scheme (the purple/blue/green category accent colors are separate)
|
| 199 |
-
- No changes beyond the 4 files listed above
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|