* 2. Include this script: * 3. Create charts with minimal configuration - colors are auto-applied! */ (function() { 'use strict'; // ========================================================================== // READ COLORS FROM CSS CUSTOM PROPERTIES // This ensures chart colors stay in sync with the theme // ========================================================================== /** * Get a CSS custom property value from :root */ function getCSSVar(name, fallback = '') { if (typeof getComputedStyle === 'undefined') return fallback; const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim(); return value || fallback; } /** * Build palette from CSS custom properties (with fallbacks) */ function buildPaletteFromCSS() { return { // Primary brand colors dartmouthGreen: getCSSVar('--dartmouth-green', '#00693e'), textPrimary: getCSSVar('--text-primary', '#0a2518'), textSecondary: getCSSVar('--text-secondary', '#0a3d23'), // Chart colors (from CSS --chart-color-N variables) chartColors: [ getCSSVar('--chart-color-1', '#00693e'), getCSSVar('--chart-color-2', '#267aba'), getCSSVar('--chart-color-3', '#ffa00f'), getCSSVar('--chart-color-4', '#9d162e'), getCSSVar('--chart-color-5', '#8a6996'), getCSSVar('--chart-color-6', '#a5d75f'), getCSSVar('--chart-color-7', '#003c73'), getCSSVar('--chart-color-8', '#d94415'), getCSSVar('--chart-color-9', '#643c20'), getCSSVar('--chart-color-10', '#c4dd88'), getCSSVar('--chart-color-11', '#f5dc69'), getCSSVar('--chart-color-12', '#424141'), ], // Background colors (semi-transparent versions) chartBgColors: [ getCSSVar('--chart-bg-1', 'rgba(0, 105, 62, 0.5)'), getCSSVar('--chart-bg-2', 'rgba(38, 122, 186, 0.5)'), getCSSVar('--chart-bg-3', 'rgba(255, 160, 15, 0.5)'), getCSSVar('--chart-bg-4', 'rgba(157, 22, 46, 0.5)'), getCSSVar('--chart-bg-5', 'rgba(138, 105, 150, 0.5)'), getCSSVar('--chart-bg-6', 'rgba(165, 215, 95, 0.5)'), ], // Semantic colors positive: getCSSVar('--chart-positive', '#00693e'), negative: getCSSVar('--chart-negative', '#9d162e'), neutral: getCSSVar('--chart-neutral', '#424141'), highlight: getCSSVar('--chart-highlight', '#ffa00f'), // Grid and axis colors gridLight: getCSSVar('--chart-grid-light', 'rgba(0, 105, 62, 0.1)'), gridMedium: getCSSVar('--chart-grid-medium', 'rgba(0, 105, 62, 0.15)'), gridDark: getCSSVar('--chart-grid-dark', 'rgba(0, 105, 62, 0.2)'), axisColor: getCSSVar('--chart-axis-color', '#0a2518'), // Font fontFamily: getCSSVar('--chart-font-family', "'Avenir LT Std', 'Avenir', 'Avenir Next', -apple-system, BlinkMacSystemFont, sans-serif"), }; } // Initialize palette (will be populated when DOM is ready) let CDL_PALETTE = null; // For convenience, expose primary chart colors array let CHART_COLORS = null; // ========================================================================== // FONT CONFIGURATION // Responsive font sizes based on typical Marp slide dimensions (1280x720) // ========================================================================== const FONT_CONFIG = { sizes: { title: 22, // Chart title subtitle: 18, // Subtitle legend: 16, // Legend labels axisTitle: 18, // Axis titles axisTicks: 16, // Axis tick labels tooltip: 14, // Tooltip text dataLabels: 14, // Data labels on charts }, weight: { normal: 400, medium: 500, bold: 600, }, }; // ========================================================================== // HELPER FUNCTIONS // ========================================================================== /** * Ensure palette is initialized */ function ensurePalette() { if (!CDL_PALETTE) { CDL_PALETTE = buildPaletteFromCSS(); CHART_COLORS = CDL_PALETTE.chartColors; } return CDL_PALETTE; } /** * Get color for a dataset at given index * Cycles through palette if more datasets than colors */ function getColor(index) { ensurePalette(); return CHART_COLORS[index % CHART_COLORS.length]; } /** * Get color with alpha transparency */ function getColorWithAlpha(color, alpha) { // Handle hex colors if (color.startsWith('#')) { const r = parseInt(color.slice(1, 3), 16); const g = parseInt(color.slice(3, 5), 16); const b = parseInt(color.slice(5, 7), 16); return `rgba(${r}, ${g}, ${b}, ${alpha})`; } // Handle rgba colors if (color.startsWith('rgba')) { return color.replace(/[\d.]+\)$/, `${alpha})`); } return color; } /** * Generate colors for all datasets in chart data * Automatically assigns colors if not specified */ function autoAssignColors(data, chartType) { if (!data || !data.datasets) return data; data.datasets.forEach((dataset, index) => { const baseColor = getColor(index); // Only assign colors if not already specified switch (chartType) { case 'bar': case 'horizontalBar': if (!dataset.backgroundColor) { dataset.backgroundColor = baseColor; } if (!dataset.borderColor) { dataset.borderColor = baseColor; } if (dataset.borderWidth === undefined) { dataset.borderWidth = 2; } break; case 'line': if (!dataset.borderColor) { dataset.borderColor = baseColor; } if (!dataset.backgroundColor) { dataset.backgroundColor = getColorWithAlpha(baseColor, 0.1); } if (dataset.borderWidth === undefined) { dataset.borderWidth = 3; } if (dataset.pointRadius === undefined) { dataset.pointRadius = 6; } if (!dataset.pointBackgroundColor) { dataset.pointBackgroundColor = baseColor; } if (dataset.tension === undefined) { dataset.tension = 0.3; } break; case 'scatter': case 'bubble': if (!dataset.backgroundColor) { dataset.backgroundColor = baseColor; } if (!dataset.borderColor) { dataset.borderColor = baseColor; } if (dataset.pointRadius === undefined) { dataset.pointRadius = 15; } if (dataset.pointHoverRadius === undefined) { dataset.pointHoverRadius = 18; } break; case 'pie': case 'doughnut': case 'polarArea': // For pie charts, we need multiple colors for one dataset if (!dataset.backgroundColor) { const numItems = dataset.data ? dataset.data.length : 6; dataset.backgroundColor = []; for (let i = 0; i < numItems; i++) { dataset.backgroundColor.push(getColor(i)); } } if (!dataset.borderColor) { dataset.borderColor = '#d8d8d8'; // Slide background } if (dataset.borderWidth === undefined) { dataset.borderWidth = 2; } break; case 'radar': if (!dataset.borderColor) { dataset.borderColor = baseColor; } if (!dataset.backgroundColor) { dataset.backgroundColor = getColorWithAlpha(baseColor, 0.2); } if (dataset.borderWidth === undefined) { dataset.borderWidth = 2; } if (dataset.pointRadius === undefined) { dataset.pointRadius = 4; } if (!dataset.pointBackgroundColor) { dataset.pointBackgroundColor = baseColor; } break; default: // Generic color assignment if (!dataset.backgroundColor) { dataset.backgroundColor = baseColor; } if (!dataset.borderColor) { dataset.borderColor = baseColor; } } }); return data; } // ========================================================================== // CHART.JS GLOBAL DEFAULTS // ========================================================================== function applyGlobalDefaults() { if (typeof Chart === 'undefined') { console.warn('Chart.js not loaded. chart-defaults.js requires Chart.js to be loaded first.'); return false; } // Ensure palette is loaded from CSS const palette = ensurePalette(); // Font defaults Chart.defaults.font.family = palette.fontFamily; Chart.defaults.font.size = FONT_CONFIG.sizes.axisTicks; Chart.defaults.color = palette.textPrimary; // Responsive defaults Chart.defaults.responsive = true; Chart.defaults.maintainAspectRatio = false; // Animation (subtle) Chart.defaults.animation.duration = 400; // Plugin defaults // Legend Chart.defaults.plugins.legend.labels.font = { family: palette.fontFamily, size: FONT_CONFIG.sizes.legend, weight: FONT_CONFIG.weight.normal, }; Chart.defaults.plugins.legend.labels.color = palette.textPrimary; Chart.defaults.plugins.legend.labels.usePointStyle = true; Chart.defaults.plugins.legend.labels.padding = 20; // Title Chart.defaults.plugins.title.font = { family: palette.fontFamily, size: FONT_CONFIG.sizes.title, weight: FONT_CONFIG.weight.medium, }; Chart.defaults.plugins.title.color = palette.textPrimary; // Tooltip Chart.defaults.plugins.tooltip.backgroundColor = palette.textPrimary; Chart.defaults.plugins.tooltip.titleFont = { family: palette.fontFamily, size: FONT_CONFIG.sizes.tooltip, weight: FONT_CONFIG.weight.medium, }; Chart.defaults.plugins.tooltip.bodyFont = { family: palette.fontFamily, size: FONT_CONFIG.sizes.tooltip, }; Chart.defaults.plugins.tooltip.cornerRadius = 4; Chart.defaults.plugins.tooltip.padding = 10; // Scale defaults (for cartesian charts) // These need to be applied per-scale type const scaleDefaults = { grid: { color: palette.gridLight, lineWidth: 1, }, border: { color: palette.gridDark, width: 1, }, ticks: { font: { family: palette.fontFamily, size: FONT_CONFIG.sizes.axisTicks, }, color: palette.textPrimary, }, title: { font: { family: palette.fontFamily, size: FONT_CONFIG.sizes.axisTitle, weight: FONT_CONFIG.weight.normal, }, color: palette.textPrimary, }, }; // Apply scale defaults to linear scale if (Chart.defaults.scales && Chart.defaults.scales.linear) { if (Chart.defaults.scales.linear.grid) Object.assign(Chart.defaults.scales.linear.grid, scaleDefaults.grid); if (Chart.defaults.scales.linear.border) Object.assign(Chart.defaults.scales.linear.border, scaleDefaults.border); if (Chart.defaults.scales.linear.ticks) Object.assign(Chart.defaults.scales.linear.ticks, scaleDefaults.ticks); if (Chart.defaults.scales.linear.title) Object.assign(Chart.defaults.scales.linear.title, scaleDefaults.title); } // Apply scale defaults to category scale if (Chart.defaults.scales && Chart.defaults.scales.category) { if (Chart.defaults.scales.category.grid) Object.assign(Chart.defaults.scales.category.grid, scaleDefaults.grid); if (Chart.defaults.scales.category.border) Object.assign(Chart.defaults.scales.category.border, scaleDefaults.border); if (Chart.defaults.scales.category.ticks) Object.assign(Chart.defaults.scales.category.ticks, scaleDefaults.ticks); if (Chart.defaults.scales.category.title) Object.assign(Chart.defaults.scales.category.title, scaleDefaults.title); } // Apply scale defaults to logarithmic scale if (Chart.defaults.scales && Chart.defaults.scales.logarithmic) { if (Chart.defaults.scales.logarithmic.grid) Object.assign(Chart.defaults.scales.logarithmic.grid, scaleDefaults.grid); if (Chart.defaults.scales.logarithmic.border) Object.assign(Chart.defaults.scales.logarithmic.border, scaleDefaults.border); if (Chart.defaults.scales.logarithmic.ticks) Object.assign(Chart.defaults.scales.logarithmic.ticks, scaleDefaults.ticks); if (Chart.defaults.scales.logarithmic.title) Object.assign(Chart.defaults.scales.logarithmic.title, scaleDefaults.title); } // Apply scale defaults to radial scale (for radar charts) if (Chart.defaults.scales && Chart.defaults.scales.radialLinear) { if (Chart.defaults.scales.radialLinear.grid) Chart.defaults.scales.radialLinear.grid.color = palette.gridLight; if (Chart.defaults.scales.radialLinear.angleLines) Chart.defaults.scales.radialLinear.angleLines.color = palette.gridMedium; if (Chart.defaults.scales.radialLinear.pointLabels) { Chart.defaults.scales.radialLinear.pointLabels.font = { family: palette.fontFamily, size: FONT_CONFIG.sizes.axisTicks, }; Chart.defaults.scales.radialLinear.pointLabels.color = palette.textPrimary; } } return true; } // ========================================================================== // CHART WRAPPER FOR AUTO-STYLING // ========================================================================== /** * Wrap the Chart constructor to automatically apply CDL styling */ function wrapChartConstructor() { if (typeof Chart === 'undefined') return; const OriginalChart = Chart; // Create a wrapper that auto-applies colors window.Chart = function(ctx, config) { // Auto-assign colors if not specified if (config && config.data) { config.data = autoAssignColors(config.data, config.type); } // Merge default options for specific chart types if (config && config.options) { config.options = applyChartTypeDefaults(config.type, config.options); } // Call original constructor return new OriginalChart(ctx, config); }; // Copy static properties and methods Object.setPrototypeOf(window.Chart, OriginalChart); Object.assign(window.Chart, OriginalChart); // Preserve the prototype chain window.Chart.prototype = OriginalChart.prototype; } /** * Apply chart-type specific defaults */ function applyChartTypeDefaults(chartType, userOptions) { const options = { ...userOptions }; switch (chartType) { case 'bar': case 'horizontalBar': // Bar chart defaults if (!options.scales) options.scales = {}; if (!options.scales.x) options.scales.x = {}; if (!options.scales.y) options.scales.y = {}; // Hide x-axis grid for cleaner look if (options.scales.x.grid === undefined) { options.scales.x.grid = { display: false }; } break; case 'line': // Line chart defaults if (!options.interaction) { options.interaction = { intersect: false, mode: 'index' }; } break; case 'pie': case 'doughnut': // Pie/doughnut defaults if (!options.plugins) options.plugins = {}; if (options.plugins.legend === undefined) { const palette = ensurePalette(); options.plugins.legend = { position: 'right', labels: { font: { family: palette.fontFamily, size: FONT_CONFIG.sizes.legend, }, color: palette.textPrimary, padding: 15, }, }; } break; case 'radar': // Radar chart defaults - keep as-is, scale defaults applied globally break; case 'scatter': case 'bubble': // Scatter/bubble defaults if (!options.scales) options.scales = {}; if (!options.scales.x) options.scales.x = {}; if (!options.scales.y) options.scales.y = {}; break; } return options; } // ========================================================================== // CONVENIENCE FUNCTIONS FOR USERS // Exposed on window.CDLChart for easy access // ========================================================================== window.CDLChart = { // Color palette access (getters to ensure lazy initialization) get colors() { return ensurePalette().chartColors; }, get palette() { return ensurePalette(); }, // Get specific color by index getColor: getColor, // Get color with transparency getColorWithAlpha: getColorWithAlpha, // Get array of colors for a specific count getColors: function(count) { ensurePalette(); const result = []; for (let i = 0; i < count; i++) { result.push(getColor(i)); } return result; }, // Font configuration fonts: FONT_CONFIG, // Quick chart creation helpers // These create minimal config that auto-applies all styling /** * Create a simple bar chart * @param {string} canvasId - Canvas element ID * @param {string[]} labels - X-axis labels * @param {number[]} data - Data values * @param {object} options - Optional overrides */ bar: function(canvasId, labels, data, options = {}) { return new Chart(document.getElementById(canvasId), { type: 'bar', data: { labels: labels, datasets: [{ data: data }], }, options: { plugins: { legend: { display: false } }, ...options, }, }); }, /** * Create a simple line chart * @param {string} canvasId - Canvas element ID * @param {string[]} labels - X-axis labels * @param {Array} datasets - Array of {label, data} objects * @param {object} options - Optional overrides */ line: function(canvasId, labels, datasets, options = {}) { return new Chart(document.getElementById(canvasId), { type: 'line', data: { labels: labels, datasets: datasets.map(ds => ({ label: ds.label, data: ds.data, fill: ds.fill !== undefined ? ds.fill : true, })), }, options: options, }); }, /** * Create a simple pie chart * @param {string} canvasId - Canvas element ID * @param {string[]} labels - Slice labels * @param {number[]} data - Data values * @param {object} options - Optional overrides */ pie: function(canvasId, labels, data, options = {}) { return new Chart(document.getElementById(canvasId), { type: 'pie', data: { labels: labels, datasets: [{ data: data }], }, options: options, }); }, /** * Create a simple scatter chart * @param {string} canvasId - Canvas element ID * @param {Array} datasets - Array of {label, data: [{x, y}]} objects * @param {object} options - Optional overrides */ scatter: function(canvasId, datasets, options = {}) { return new Chart(document.getElementById(canvasId), { type: 'scatter', data: { datasets: datasets.map(ds => ({ label: ds.label, data: ds.data, })), }, options: options, }); }, /** * Create a doughnut chart * @param {string} canvasId - Canvas element ID * @param {string[]} labels - Slice labels * @param {number[]} data - Data values * @param {object} options - Optional overrides */ doughnut: function(canvasId, labels, data, options = {}) { return new Chart(document.getElementById(canvasId), { type: 'doughnut', data: { labels: labels, datasets: [{ data: data }], }, options: options, }); }, /** * Create a radar chart * @param {string} canvasId - Canvas element ID * @param {string[]} labels - Axis labels * @param {Array} datasets - Array of {label, data} objects * @param {object} options - Optional overrides */ radar: function(canvasId, labels, datasets, options = {}) { return new Chart(document.getElementById(canvasId), { type: 'radar', data: { labels: labels, datasets: datasets.map(ds => ({ label: ds.label, data: ds.data, })), }, options: options, }); }, }; // ========================================================================== // INITIALIZATION // ========================================================================== function initialize() { // Wait for Chart.js to be available if (typeof Chart !== 'undefined') { applyGlobalDefaults(); wrapChartConstructor(); console.log('CDL Chart defaults applied successfully.'); return true; } else { // Chart.js not yet loaded - wait and retry let retries = 0; const maxRetries = 50; // 5 seconds max wait const checkInterval = setInterval(function() { retries++; if (typeof Chart !== 'undefined') { clearInterval(checkInterval); applyGlobalDefaults(); wrapChartConstructor(); console.log('CDL Chart defaults applied successfully (after waiting for Chart.js).'); } else if (retries >= maxRetries) { clearInterval(checkInterval); console.warn('Chart.js not found after waiting. CDL Chart defaults not applied.'); } }, 100); return false; } } // Initialize IMMEDIATELY - this must run BEFORE any chart creation scripts // Chart.js CDN should be loaded before this script initialize(); })();

Lecture 1: Course introduction

PSYC 51.07: Models of language and communication

Jeremy R. Manning
Dartmouth College
Winter 2026

Who am I?

Jeremy R. Manning, Ph.D.

Associate Professor | Psychological & Brain Sciences | | Moore 349

Research focus

How do our brains support our ongoing conscious thoughts, and how (and what) do we remember?

Key areas

Learning and memory, education technology, brain network dynamics, data science, NLP

Approach

Theory, models, experiments, neuroimaging

Training

B.S., Neuroscience & Computer Science
Ph.D., Neuroscience
Postdoc, Computer Science & Neuroscience

Funding & collaborators

NIH NSF DARPA BrainFit
Intel Labs Meta Google Amazon

What is this course about?

We will explore how machines can understand and generate human language:

  • Building conversational agents from scratch
  • Understanding how language relates to thought
  • Hands-on programming with real models
  • Critical thinking about AI consciousness

This course is experiential! You will learn by doing: coding, experimenting, discussing, and researching.

Course structure

  • Weekly (roughly) short projects (5): 75%
  • Final project: 25%
    • Can work individually or in groups
  • See syllabus for additional details
  • Google Colaboratory
  • HuggingFace
  • GitHub / Discord
  • GenAI (Claude, ChatGPT, Gemini)

The big questions

  1. Can machines truly understand language?
  2. What is the relationship between language and thought?
  3. Can statistical patterns capture meaning? How? Under which circumstances?
  4. Can AI be conscious? If so, what are the implications?

These are not just "fluff" questions: they are at the heart of cognitive science, philosophy, psychology, and neuroscience!

Discussion: is ChatGPT conscious?

  • What does "conscious" even mean?
  • How would we test for consciousness?
  • Does it matter if ChatGPT seems conscious?

What are the implications for:

  • Ourselves
  • Other animals
  • Other life forms in general (aliens? synthetic life?)
  • Policy, ethics, and society more broadly

What is consciousness?

  • Phenomenal: Subjective experience—the "what it is like" quality of sensations and emotions
  • Access: Information available for reasoning, reporting, and guiding voluntary behavior
  • Self-awareness: Knowledge of one's own mental states, including recognizing oneself as a distinct entity
Example of phenomenal consciousness The redness of red, pain, taste of coffee
Example of access consciousness Being able to report on and use information to guide behavior
Example of self-awareness Knowing that you are thinking, or recognizing your own emotions

If ChatGPT says "I feel happy," does it actually feel anything?

The hard problem

Humans

  • Share similar biology
  • Have our own conscious experiences
  • Behave consistently with having experiences (e.g., of being human, living in the world, etc.)

AI

  • Completely different "biology" (silicon vs. neurons)
  • No shared evolutionary history
  • Can produce human-like behavior without themselves being human

We cannot directly observe consciousness — even in other humans!

The Chinese room argument

  • Thought experiment about understanding vs. simulation.
  • The setup: Person in room with Chinese symbols and rule book
  • Does following rules = understanding? Searle argues: No!
Chinese question Rule book Chinese answer
Person follows rules but does not understand Chinese

The Chinese room argument

The scenario:

  1. You are locked in a room
  2. Chinese characters slide under the door
  3. You look them up in a rule book
  4. You copy out the corresponding response
  5. You slide it back out

Observer sees: Perfect Chinese conversation!
Your perspective: Just symbol manipulation.

Concrete example:


1Input:  你好吗? (How are you?)
2Lookup: Rule #42,938 → 我很好
3Output: 我很好 (I am fine)

You matched symbols without knowing:

  • What "你好吗" means
  • That it's a greeting
  • What "你" (you) refers to

Syntax (symbol manipulation) is not sufficient for semantics (meaning).

Volition

  • Another critical aspect of the human conscious experience is the ability to decide (how to act, what to think, etc.)
  • Modern LLMs are trained to respond to other inputs (i.e., produce statistically likely sequence completions), but they cannot themselves initiate new or unexpected actions

LLMs are like a bellows that can only blow air if someone else is pumping it. When not in use, they are static. They can not sense the passage of time. They cease to exist between invocations.

Current scientific consensus

Most cognitive scientists and AI researchers agree: current LLMs are not conscious.

  • No sensory-motor grounding in the world
  • No persistent self-model or goals
  • Pattern matching \neq understanding

Another angle: relating language and thought

Do you need language to think? Does language shape how you think?

  • Possibility 1: Language is necessary for thought
  • Possibility 2: Language is just a tool for communication

⚖️

The language-thought spectrum

Strong Whorfian Weak Whorfian Moderate Language-of-Thought
Language shapes thought (left) to language independent of thought (right)

Current evidence points toward the middle: language and thought interact in complex ways, but are not identical.

Evidence: the language network

Fedorenko et al. (2024, Nature): The language network as a natural kind

Stanford Encyclopdia of Philosophy: Whorfianism

  • The brain has a specialized language network
  • Distinct (as measured using neuroimaging and lesion studies) from: reasoning, math, social cognition, music
  • Implication: Language and thought are separable in the brain!

Brain networks

💬 Language
🤔 Reasoning
🤝 Social
📊 Math

Language is a specialized system, not the basis of all thought! This has fascinating implications for LLMs: we've built machines that can interact using language, but this doesn't necessarily mean they understand it in any recognizable way.

However, language can shape thought

Lupyan et al. (2020, TiCS): Effects of language on visual perception

Having words for things affects how we see them:

  • Speed up visual search
  • Alter color perception
  • Influence object categorization

Example: Russian blue

English: "blue"
English: "blue"
Russian: "siniy"
Russian: "goluboy"

English speakers are slower to distinguish shades of blue than Russian speakers:
language categories affect perception, not just description!

Example: Russian blue

English: "blue"
English: "blue"
Russian: "siniy"
Russian: "goluboy"
  • Having distinct words for colors creates perceptual boundaries
  • The brain literally processes colors faster when they cross linguistic categories
  • Language doesn't just describe reality; it shapes how we see it

If language shapes perception, what "perception" do LLMs have? They experience language about color, but never color itself.

The grounding problem

How do symbols (words) get their meaning?

  • For humans, the meanings of symbols are learned through experience:
    • See, touch, taste objects
    • Act in the world
    • We learn to associate symbols with our experiences
  • For LLMs, the meanings of symbols are learned through statistics:
    • Learn patterns in text
    • Generate text based on those patterns
    • No direct connection with the external world

The grounding problem example: what is "coffee"

Humans learn about coffee through experience:

  • Bitter taste
  • Rich aroma
  • Warm ceramic mug
  • Morning ritual feeling
  • Caffeine effect on body

These experiences ground the word.

LLMs learn about coffee through statistics:

  • Often appears with "morning"
  • Frequently near "cup", "drink"
  • Associated with "caffeine"
  • Patterns: "I need my ___"
  • Context: restaurants, breakfast

This is pure pattern matching, not experience-based.

Can statistical patterns ever capture what it feels like to drink coffee? Does human learning not amount to statistics? Is it about the style of learning per se, our about the kinds of data we are learning from?

How LLMs actually work: a preview

At their core, LLMs are trained to predict what comes next. Given a sequence of words, what is the most likely continuation?

Suppose we start with some input text: "The cat sat on the"

LLMs predict probability for each possible next word:


1predictions = {
2    "mat": 0.35,       # Most likely
3    "floor": 0.20,
4    "couch": 0.15,
5    "roof": 0.05,
6    "elephant": 0.001  # Very unlikely
7}

LLMs don't "know" what cats are. They've just seen "cat sat on the mat" many times!

Our approach (in this course)

We will build language models from scratch to understand what they can and cannot do. By learning about the inner workings of LLMs, we can better understand their capabilities and limitations and our own capabilities and limitations.

String manipulation Classifiers Embeddings Retrieval systems LLMs
You'll progress from building simple string manipulation models to modern LLMs. We will make heavy use of GenAI (vibe coding) to enable us to build and iterate quickly.

Up next...

Pattern matching and ELIZA

  • Introduction to ELIZA
  • The ELIZA effect
  • String manipulation and regular expressions

ELIZA implementation

  • Complete architecture
  • Assignment 1 details
  • Coding together (time permitting)

Required readings for this week

  1. Weizenbaum (1966): ELIZA
  2. Fedorenko et al. (2024): The language network
  3. Lupyan et al. (2020): Effects of language on visual perception

Start with Weizenbaum— it will help you understand the fundamentals and give you important historical context!

Key ideas from today

  1. Consciousness is complex: multiple types, hard to define
  2. Language \neq Thought: but they interact in interesting ways
  3. LLMs are not conscious: they are sophisticated pattern matchers
  4. Grounding matters: meaning comes from experience
  5. Building to understand: we'll build (and play around with) real models to understand what they can and can't do

Questions? Want to chat more?

📧 Email me
💬 Join our Discord
💁 Come to office hours

This course will move very quickly. Please reach out if you have questions, comments, concerns, or just want to chat!