STAT 214 Spring 2026
Week 13 Discussion
Lab 3.2: BERT & LoRA Fine-Tuning
4/17/2026
GSI: Sean Richardson
2
Announcements
Office hours
Lab 3 reminders
Reference guides
smrichardson.github.io/stat214
3
Where we are in Lab 3
| What | Due | Status |
3.1 | BoW, Word2Vec, GloVe → ridge → CC | Apr 10 | Done! |
3.2 | BERT + LoRA → ridge → compare all | Apr 24 | ← you are here |
3.3 | SHAP/LIME interpretation + final report | May 8 | |
Today's focus: everything you need for 3.2
The good news: your pipeline from 3.1 carries over. The only new part is the embedding step.
Remaining discussions:
4
Outline
~ 5 min
~ 5 min
~ 15 min
~ 10 min
~ 15 min
5
About me
Sean Richardson
he/him · seanrichardson@berkeley.edu
Research interests:
Taking over from Sequoia for the rest of the semester
6
3.1 Debrief
What was your experience with 3.1?
Memory? Storage? Bridges-2?
Most voxels near zero is expected!
7
Why fine-tune BERT?
Fine-tuning adapts the representations to our domain:
Question: BERT has ~110 million parameters. Our story data has ~24,000 words. Does anyone see a problem?
8
Why fine-tune BERT?
Fine-tuning adapts the representations to our domain:
Question: BERT has ~110 million parameters. Our story data has ~24,000 words. Does anyone see a problem?
Massive overfitting risk! We need a way to fine-tune with far fewer parameters → “parameter-efficient finetuning.” Also offers big compute savings!
9
LoRA: Low-Rank Adaptation
Key idea
We can probably find a good task-specific weight update within a low-dimensional subspace
Linear algebra review:�
10
LoRA: Low-Rank Adaptation
Key idea
We can probably find a good task-specific weight update within a low-dimensional subspace – which corresponds to the span of some low-rank matrix
11
LoRA: Low-Rank Adaptation
Key idea
We can probably find a good task-specific weight update within a low-dimensional subspace – which corresponds to the span of some low-rank matrix�
12
LoRA: Low-Rank Adaptation
Key idea
We can probably find a good task-specific weight update within a low-dimensional subspace – which corresponds to the span of some low-rank matrix�
13
LoRA: Low-Rank Adaptation
Steps
Instead of updating the full weight matrix W:
1. Freeze W (e.g., all original BERT parameters)
2. Add small trainable matrices A and B
3. The update is: ΔW = (γ/r) · A · Bᵀ
where r is the rank (e.g. 4 or 8), and γ is a scaling hyperparameter
Example dimensions
Original W: 768 × 768
= 590K parameters
LoRA (rank 8):
A: 768 × 8
B: 768 × 8
= 12K parameters
98% reduction!
14
LoRA intuition: PCA for weight updates
Think of it like PCA:
Where do we apply LoRA?
15
Hyperparameters to explore
Parameter | What it controls | Start with | Try |
Rank (r) | Capacity of adaptation | 8 | 4, 8, 16 |
lora_alpha (γ) | Update magnitude | 8 | r to 2r |
Target modules | Which attention weights | Q + V | Add K |
Learning rate | Optimizer step size | 1e-4 | 1e-4 to 5e-4 |
Epochs | Passes over data | 3 | 3-5 |
A full sweep of all hyperparameters is not expected. More systematic approaches exist (e.g. Bayesian optimization), but grid search over a few values is fine for this lab.
16
Practical: extracting BERT embeddings
Quick question: how many r's are in "strawberry"?
Why do LLMs famously get this wrong?
17
Practical: extracting BERT embeddings
LLMs don't see letters — they see tokens (subwords).
The subword problem
BERT tokenizes into subwords, not words:
"playing" → ["play", "##ing"] (2 vectors, but we need 1)
The 512-token limit
18
Important: two different BERT classes
BertModel
(for extracting embeddings)
Output: last_hidden_state
Shape: (seq_len, 768)
These are the contextual embeddings you want for the pipeline
BertForMaskedLM
(for training with MLM loss)
Output: logits
Shape: (seq_len, 30522)
These are vocabulary predictions, NOT embeddings!
19
The 3.2 pipeline (what's new vs 3.1)
Same as 3.1:
Downsample → Delays → Trim → Ridge → CC evaluation
New for 3.2 (the embedding step only):
1. Extract embeddings from pretrained BERT (no training)
→ Handle subword aggregation and 512-token limit
2. Fine-tune BERT with LoRA on MLM objective
→ Tokenize stories into overlapping chunks
→ Train with DataCollatorForLanguageModeling (handles masking)
→ Save the LoRA adapter
3. Extract embeddings from fine-tuned BERT
→ Load adapter onto BertModel, use same extraction code
4. Compare all methods: BoW, W2V, GloVe, BERT, BERT+LoRA
20
Questions to address in your report
Does fine-tuning actually help?
Compare pretrained vs LoRA-finetuned BERT. If it doesn't help, why?
Do contextual embeddings predict different voxels?
Jaccard similarity of top voxel sets across embedding methods
Data leakage?
You fine-tune on story text, then use the same text for ridge. The MLM never sees fMRI data. Discuss.
Stability of LoRA hyperparameters
If changing rank flips which voxels are well-predicted, the conclusions are fragile (PCS!)
Weight interpretability
Why can't we just look at the ridge weights? (Answer: embedding dimensions aren't interpretable. SHAP/LIME in 3.3.)
21
Upcoming sessions
Next week (4/24): SHAP & LIME interpretation
You'll need this for Lab 3.3. I'll cover the wrapper pattern, how SHAP and LIME work, and practical tips for running them on your models.
Last session (5/1): your choice!
Potential outcomes, DAGs, common identification strategies
Reward modeling, policy optimization, DeepSeek-style reasoning RL
Show of hands at the end?
Questions?
Lab work time — I'm here to help with 3.2