fix(demo-04): Update attention visualizer to use shared theming system #48
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Deploy Slides | ||
| on: | ||
| push: | ||
| branches: [ main, master ] | ||
| paths: | ||
| - 'slides/**/*.tex' | ||
| - 'slides/**/*.ipynb' | ||
| - 'admin/syllabus.md' | ||
| - '.github/workflows/build-slides.yml' | ||
| pull_request: | ||
| branches: [ main, master ] | ||
| paths: | ||
| - 'slides/**/*.tex' | ||
| - 'slides/**/*.ipynb' | ||
| - 'admin/syllabus.md' | ||
| workflow_dispatch: | ||
| permissions: | ||
| contents: read | ||
| pages: write | ||
| id-token: write | ||
| concurrency: | ||
| group: "pages" | ||
| cancel-in-progress: false | ||
| jobs: | ||
| build-slides: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| - name: Install LaTeX | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y \ | ||
| texlive-latex-base \ | ||
| texlive-latex-extra \ | ||
| texlive-fonts-recommended \ | ||
| texlive-fonts-extra \ | ||
| texlive-xetex \ | ||
| texlive-luatex \ | ||
| texlive-science \ | ||
| latexmk \ | ||
| pdf2svg \ | ||
| pandoc \ | ||
| fonts-firacode \ | ||
| fonts-noto-color-emoji \ | ||
| fonts-font-awesome | ||
| # Update font cache | ||
| sudo fc-cache -f -v | ||
| - name: Verify Fira Code font installation | ||
| run: | | ||
| # Verify font installation | ||
| fc-list | grep -i "fira" || echo "Warning: Fira Code font may not be installed correctly" | ||
| - name: Set up Python | ||
| uses: actions/setup-python@v4 | ||
| with: | ||
| python-version: '3.11' | ||
| - name: Install Jupyter and nbconvert | ||
| run: | | ||
| pip install jupyter nbconvert | ||
| - name: Compile syllabus PDF | ||
| run: | | ||
| echo "📄 Compiling syllabus..." | ||
| cd admin | ||
| # Use lualatex (required for emoji package) | ||
| pandoc -s -o syllabus.pdf syllabus.md --pdf-engine=lualatex || \ | ||
| pandoc -s -o syllabus.pdf syllabus.md --pdf-engine=xelatex || \ | ||
| pandoc -s -o syllabus.pdf syllabus.md --pdf-engine=pdflatex | ||
| if [ -f syllabus.pdf ]; then | ||
| echo "✅ Successfully compiled syllabus.pdf" | ||
| else | ||
| echo "❌ Failed to compile syllabus.pdf" | ||
| fi | ||
| cd .. | ||
| - name: Find and compile all lecture slides | ||
| run: | | ||
| echo "🔍 Finding all .tex files in slides directory..." | ||
| find slides -name "*.tex" -type f | while read -r tex_file; do | ||
| dir=$(dirname "$tex_file") | ||
| filename=$(basename "$tex_file" .tex) | ||
| echo "📝 Compiling $tex_file..." | ||
| cd "$dir" | ||
| # Try lualatex first (required for emoji package) | ||
| if lualatex -interaction=nonstopmode -halt-on-error "$filename.tex" > /dev/null 2>&1; then | ||
| lualatex -interaction=nonstopmode -halt-on-error "$filename.tex" > /dev/null 2>&1 || true | ||
| else | ||
| echo "⚠️ lualatex failed, trying xelatex..." | ||
| # Try xelatex (better Unicode support) | ||
| if xelatex -interaction=nonstopmode -halt-on-error "$filename.tex" > /dev/null 2>&1; then | ||
| xelatex -interaction=nonstopmode -halt-on-error "$filename.tex" > /dev/null 2>&1 || true | ||
| else | ||
| echo "⚠️ xelatex failed, trying pdflatex..." | ||
| # Fall back to pdflatex | ||
| pdflatex -interaction=nonstopmode -halt-on-error "$filename.tex" > /dev/null 2>&1 || true | ||
| pdflatex -interaction=nonstopmode -halt-on-error "$filename.tex" > /dev/null 2>&1 || true | ||
| fi | ||
| fi | ||
| cd - > /dev/null | ||
| if [ -f "$dir/$filename.pdf" ]; then | ||
| echo "✅ Successfully compiled $tex_file to $filename.pdf" | ||
| else | ||
| echo "❌ Failed to compile $tex_file" | ||
| fi | ||
| done | ||
| - name: Convert Jupyter notebooks to HTML | ||
| run: | | ||
| echo "🔍 Finding all .ipynb files in slides directory..." | ||
| find slides -name "*.ipynb" -type f | while read -r notebook; do | ||
| dir=$(dirname "$notebook") | ||
| filename=$(basename "$notebook" .ipynb) | ||
| echo "📓 Converting $notebook to HTML..." | ||
| jupyter nbconvert --to html "$notebook" --output "$filename.html" || true | ||
| if [ -f "$dir/$filename.html" ]; then | ||
| echo "✅ Successfully converted $notebook" | ||
| else | ||
| echo "❌ Failed to convert $notebook" | ||
| fi | ||
| done | ||
| - name: Create HTML viewers for slides with Dartmouth branding | ||
| run: | | ||
| echo "🌐 Creating HTML viewers for PDFs with Dartmouth branding..." | ||
| find slides -name "*.pdf" -type f | while read -r pdf_file; do | ||
| dir=$(dirname "$pdf_file") | ||
| filename=$(basename "$pdf_file" .pdf) | ||
| # Create HTML viewer with Dartmouth branding (matching syllabus link format) | ||
| cat > "$dir/${filename}.html" << 'VIEWER_EOF' | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>FILENAME_PLACEHOLDER - PSYC 51.07</title> | ||
| <style> | ||
| * { margin: 0; padding: 0; box-sizing: border-box; } | ||
| body { | ||
| font-family: 'Helvetica Neue', Arial, sans-serif; | ||
| background: #f5f5f5; | ||
| color: #333; | ||
| } | ||
| .header { | ||
| background: #00693e; /* Dartmouth Green */ | ||
| padding: 15px 20px; | ||
| display: flex; | ||
| justify-content: space-between; | ||
| align-items: center; | ||
| box-shadow: 0 2px 10px rgba(0,0,0,0.2); | ||
| } | ||
| .header h1 { | ||
| color: white; | ||
| font-size: 1.4em; | ||
| font-weight: 500; | ||
| } | ||
| .header .nav { | ||
| display: flex; | ||
| gap: 10px; | ||
| } | ||
| .header a { | ||
| color: white; | ||
| text-decoration: none; | ||
| padding: 8px 16px; | ||
| background: rgba(255,255,255,0.15); | ||
| border-radius: 4px; | ||
| font-size: 0.9em; | ||
| transition: background 0.2s; | ||
| } | ||
| .header a:hover { background: rgba(255,255,255,0.25); } | ||
| .pdf-container { | ||
| width: 100%; | ||
| height: calc(100vh - 60px); | ||
| } | ||
| iframe { | ||
| width: 100%; | ||
| height: 100%; | ||
| border: none; | ||
| } | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <div class="header"> | ||
| <h1>FILENAME_PLACEHOLDER - Models of Language and Communication</h1> | ||
| <div class="nav"> | ||
| <a href="FILENAME_PLACEHOLDER.pdf" download>Download PDF</a> | ||
| <a href="../../index.html">All Slides</a> | ||
| <a href="https://github.com/ContextLab/llm-course">GitHub</a> | ||
| </div> | ||
| </div> | ||
| <div class="pdf-container"> | ||
| <iframe src="FILENAME_PLACEHOLDER.pdf"></iframe> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| VIEWER_EOF | ||
| # Replace placeholder with actual filename | ||
| sed -i "s/FILENAME_PLACEHOLDER/$filename/g" "$dir/${filename}.html" | ||
| echo "Created HTML viewer: $dir/${filename}.html" | ||
| done | ||
| - name: Build web directory structure | ||
| run: | | ||
| # Create web directory structure | ||
| mkdir -p web_slides/slides | ||
| mkdir -p web_slides/admin | ||
| # Copy all PDF files | ||
| echo "📦 Copying PDFs..." | ||
| find slides -name "*.pdf" -type f | while read -r pdf_file; do | ||
| rel_path=${pdf_file#slides/} | ||
| target_dir=$(dirname "web_slides/slides/$rel_path") | ||
| mkdir -p "$target_dir" | ||
| cp "$pdf_file" "web_slides/slides/$rel_path" | ||
| echo "Copied $pdf_file" | ||
| done | ||
| # Copy all HTML files (both converted notebooks and viewers) | ||
| echo "📦 Copying HTML files..." | ||
| find slides -name "*.html" -type f | while read -r html_file; do | ||
| rel_path=${html_file#slides/} | ||
| target_dir=$(dirname "web_slides/slides/$rel_path") | ||
| mkdir -p "$target_dir" | ||
| cp "$html_file" "web_slides/slides/$rel_path" | ||
| echo "Copied $html_file" | ||
| done | ||
| # Copy syllabus | ||
| echo "📦 Copying syllabus..." | ||
| cp admin/syllabus.pdf web_slides/admin/ 2>/dev/null || echo "Syllabus PDF not found" | ||
| - name: Generate index page | ||
| run: | | ||
| cat > web_slides/index.html << 'EOF' | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>LLM Course Slides - PSYC 51.07</title> | ||
| <style> | ||
| * { | ||
| margin: 0; | ||
| padding: 0; | ||
| box-sizing: border-box; | ||
| } | ||
| body { | ||
| font-family: 'Helvetica Neue', Arial, sans-serif; | ||
| background: #00693e; /* Dartmouth Green */ | ||
| min-height: 100vh; | ||
| padding: 40px 20px; | ||
| } | ||
| .container { | ||
| max-width: 1200px; | ||
| margin: 0 auto; | ||
| } | ||
| h1 { | ||
| color: white; | ||
| text-align: center; | ||
| font-size: 2.5em; | ||
| margin-bottom: 15px; | ||
| } | ||
| .subtitle { | ||
| color: rgba(255,255,255,0.9); | ||
| text-align: center; | ||
| font-size: 1.2em; | ||
| margin-bottom: 30px; | ||
| } | ||
| .syllabus-link { | ||
| text-align: center; | ||
| margin-bottom: 50px; | ||
| } | ||
| .syllabus-link a { | ||
| display: inline-block; | ||
| background: white; | ||
| color: #00693e; | ||
| padding: 15px 40px; | ||
| border-radius: 30px; | ||
| text-decoration: none; | ||
| font-weight: bold; | ||
| font-size: 1.1em; | ||
| box-shadow: 0 5px 20px rgba(0,0,0,0.2); | ||
| transition: transform 0.3s ease, box-shadow 0.3s ease; | ||
| } | ||
| .syllabus-link a:hover { | ||
| transform: translateY(-3px); | ||
| box-shadow: 0 8px 25px rgba(0,0,0,0.3); | ||
| } | ||
| .slides-grid { | ||
| display: grid; | ||
| grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); | ||
| gap: 30px; | ||
| margin-top: 40px; | ||
| } | ||
| .slide-card { | ||
| background: white; | ||
| border-radius: 8px; | ||
| padding: 25px; | ||
| box-shadow: 0 4px 15px rgba(0,0,0,0.15); | ||
| transition: transform 0.3s ease, box-shadow 0.3s ease; | ||
| } | ||
| .slide-card:hover { | ||
| transform: translateY(-5px); | ||
| box-shadow: 0 8px 25px rgba(0,0,0,0.2); | ||
| } | ||
| .slide-card h2 { | ||
| color: #00693e; | ||
| margin-bottom: 12px; | ||
| font-size: 1.3em; | ||
| } | ||
| .slide-card p { | ||
| color: #555; | ||
| line-height: 1.5; | ||
| margin-bottom: 15px; | ||
| font-size: 0.95em; | ||
| } | ||
| .slide-card .links { | ||
| display: flex; | ||
| gap: 8px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .slide-card .btn { | ||
| display: inline-block; | ||
| padding: 8px 16px; | ||
| border-radius: 4px; | ||
| text-decoration: none; | ||
| font-weight: 500; | ||
| transition: opacity 0.2s ease; | ||
| font-size: 0.85em; | ||
| } | ||
| .slide-card .btn:hover { | ||
| opacity: 0.85; | ||
| } | ||
| .btn-primary { | ||
| background: #00693e; | ||
| color: white; | ||
| } | ||
| .btn-secondary { | ||
| background: #267aba; /* River Blue */ | ||
| color: white; | ||
| } | ||
| .week-label { | ||
| font-size: 0.85em; | ||
| color: #888; | ||
| margin-bottom: 8px; | ||
| text-transform: uppercase; | ||
| letter-spacing: 0.5px; | ||
| } | ||
| footer { | ||
| text-align: center; | ||
| color: rgba(255,255,255,0.9); | ||
| margin-top: 60px; | ||
| padding: 20px; | ||
| } | ||
| footer a { | ||
| color: white; | ||
| text-decoration: underline; | ||
| } | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <div class="container"> | ||
| <h1>Models of Language and Communication</h1> | ||
| <p class="subtitle">PSYC 51.07 - Dartmouth College</p> | ||
| <div class="syllabus-link"> | ||
| <a href="admin/syllabus.pdf" target="_blank">📄 Download Course Syllabus</a> | ||
| </div> | ||
| <div class="slides-grid"> | ||
| <div class="slide-card"> | ||
| <p class="week-label">Week 1</p> | ||
| <h2>Introduction & String Manipulation</h2> | ||
| <p>Pattern matching, the ELIZA chatbot, and consciousness in AI.</p> | ||
| <div class="links"> | ||
| <a href="slides/week1/lecture1.pdf" class="btn btn-primary" target="_blank">Lecture 1</a> | ||
| <a href="slides/week1/lecture2.pdf" class="btn btn-primary" target="_blank">Lecture 2</a> | ||
| <a href="slides/week1/lecture3.pdf" class="btn btn-primary" target="_blank">Lecture 3</a> | ||
| <a href="slides/week1/xhour_eliza_demo.html" class="btn btn-secondary" target="_blank">X-hour</a> | ||
| </div> | ||
| </div> | ||
| <div class="slide-card"> | ||
| <p class="week-label">Week 2</p> | ||
| <h2>Computational Linguistics</h2> | ||
| <p>Tokenization, POS tagging, sentiment analysis.</p> | ||
| <div class="links"> | ||
| <a href="slides/week2/lecture4.pdf" class="btn btn-primary" target="_blank">Lecture 4</a> | ||
| <a href="slides/week2/lecture5.pdf" class="btn btn-primary" target="_blank">Lecture 5</a> | ||
| <a href="slides/week2/lecture6.pdf" class="btn btn-primary" target="_blank">Lecture 6</a> | ||
| <a href="slides/week2/xhour_classification_demo.html" class="btn btn-secondary" target="_blank">X-hour</a> | ||
| </div> | ||
| </div> | ||
| <div class="slide-card"> | ||
| <p class="week-label">Week 3</p> | ||
| <h2>Text Embeddings I</h2> | ||
| <p>LSA, LDA, Word2Vec, GloVe, FastText.</p> | ||
| <div class="links"> | ||
| <a href="slides/week3/lecture7.pdf" class="btn btn-primary" target="_blank">Lecture 7</a> | ||
| <a href="slides/week3/lecture8.pdf" class="btn btn-primary" target="_blank">Lecture 8</a> | ||
| <a href="slides/week3/xhour_embeddings_demo.html" class="btn btn-secondary" target="_blank">X-hour</a> | ||
| </div> | ||
| </div> | ||
| <div class="slide-card"> | ||
| <p class="week-label">Week 4</p> | ||
| <h2>Text Embeddings II</h2> | ||
| <p>Contextual embeddings, dimensionality reduction.</p> | ||
| <div class="links"> | ||
| <a href="slides/week4/lecture9.pdf" class="btn btn-primary" target="_blank">Lecture 9</a> | ||
| <a href="slides/week4/lecture10.pdf" class="btn btn-primary" target="_blank">Lecture 10</a> | ||
| <a href="slides/week4/lecture11.pdf" class="btn btn-primary" target="_blank">Lecture 11</a> | ||
| <a href="slides/week3-4/lecture.pdf" class="btn btn-secondary" target="_blank">Combined</a> | ||
| </div> | ||
| </div> | ||
| <div class="slide-card"> | ||
| <p class="week-label">Week 5</p> | ||
| <h2>Transformers & Attention</h2> | ||
| <p>Attention mechanisms, transformer architecture.</p> | ||
| <div class="links"> | ||
| <a href="slides/week5/lecture12.pdf" class="btn btn-primary" target="_blank">Lecture 12</a> | ||
| <a href="slides/week5/lecture13.pdf" class="btn btn-primary" target="_blank">Lecture 13</a> | ||
| <a href="slides/week5/lecture14.pdf" class="btn btn-primary" target="_blank">Lecture 14</a> | ||
| </div> | ||
| </div> | ||
| <div class="slide-card"> | ||
| <p class="week-label">Week 6</p> | ||
| <h2>Encoder Models & BERT</h2> | ||
| <p>BERT, RoBERTa, DistilBERT, applications.</p> | ||
| <div class="links"> | ||
| <a href="slides/week6/lecture15.pdf" class="btn btn-primary" target="_blank">Lecture 15</a> | ||
| <a href="slides/week6/lecture16.pdf" class="btn btn-primary" target="_blank">Lecture 16</a> | ||
| <a href="slides/week6/lecture17.pdf" class="btn btn-primary" target="_blank">Lecture 17</a> | ||
| <a href="slides/week5-6/lecture.pdf" class="btn btn-secondary" target="_blank">Combined</a> | ||
| </div> | ||
| </div> | ||
| <div class="slide-card"> | ||
| <p class="week-label">Week 7-8</p> | ||
| <h2>Decoder Models & GPT</h2> | ||
| <p>GPT architecture, autoregressive generation, scaling.</p> | ||
| <div class="links"> | ||
| <a href="slides/week7/lecture18.pdf" class="btn btn-primary" target="_blank">Lecture 18</a> | ||
| <a href="slides/week7/lecture19.pdf" class="btn btn-primary" target="_blank">Lecture 19</a> | ||
| <a href="slides/week7/lecture20.pdf" class="btn btn-primary" target="_blank">Lecture 20</a> | ||
| <a href="slides/week7/lecture.pdf" class="btn btn-secondary" target="_blank">Combined</a> | ||
| </div> | ||
| </div> | ||
| <div class="slide-card"> | ||
| <p class="week-label">Week 9</p> | ||
| <h2>Advanced Topics</h2> | ||
| <p>RAG, Mixture of Experts, ethics and safety.</p> | ||
| <div class="links"> | ||
| <a href="slides/week9/lecture21.pdf" class="btn btn-primary" target="_blank">Lecture 21</a> | ||
| <a href="slides/week9/lecture22.pdf" class="btn btn-primary" target="_blank">Lecture 22</a> | ||
| <a href="slides/week9/lecture23.pdf" class="btn btn-primary" target="_blank">Lecture 23</a> | ||
| <a href="slides/week9/lecture.pdf" class="btn btn-secondary" target="_blank">Combined</a> | ||
| </div> | ||
| </div> | ||
| <div class="slide-card"> | ||
| <p class="week-label">Week 10</p> | ||
| <h2>Final Presentations</h2> | ||
| <p>Student project presentations and course wrap-up.</p> | ||
| <div class="links"> | ||
| <a href="slides/week10/lecture24.pdf" class="btn btn-primary" target="_blank">Lecture 24</a> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <footer> | ||
| <p><a href="https://github.com/ContextLab/llm-course" target="_blank">View Course on GitHub</a></p> | ||
| <p><a href="https://contextlab.github.io/llm-course/demos/" target="_blank">Interactive Demos</a></p> | ||
| </footer> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| EOF | ||
| echo "✅ Created index page at web_slides/index.html" | ||
| - name: Setup Pages | ||
| uses: actions/configure-pages@v4 | ||
| - name: Upload artifact | ||
| uses: actions/upload-pages-artifact@v3 | ||
| with: | ||
| path: 'web_slides' | ||
| - name: Deploy to GitHub Pages | ||
| id: deployment | ||
| uses: actions/deploy-pages@v4 | ||