AO
Back

Transformer Debugging

CodingOnsiteLast reported September 2026High Frequency

Problem Overview

Before the round, the recruiter's prompt names it ML Debug: a transformer model written in PyTorch whose bugs you find and fix.

In the round you get a small GPT-style causal language model, a training loop that overfits one sentence, and a sample() function; comments mark the regions that contain bugs. When the fixes are right, the loss converges and the sample produces text. Sixty minutes, and a follow-up comes once the model works.

This editor has no PyTorch, so the model here is a numpy port of the forward pass, and the tests check each fix directly instead of training.

Part 1 — Fix the bugs

Find and fix the four planted bugs so the model is a correct next-token language model: the loss targets, the positional-embedding initialization, the causal mask, and a typo in the attention output. The tests call the static GPT.next_token_loss(logits, idx) on hand-built logits, and compare attention(x, p) with a hand computation that uses the given softmax(x, axis=-1). Fix each inside its marked region and keep the interface as given. The positional table is meant to stay learnable and the bug is its initial value; the test accepts any reasonable init (a small random one like the token embedding's, a sin/cos table, or zeros) and fails only the given unit-variance one.

Part 2 — KV cache

Make generation cheaper with a KV cache. The KV and Cache classes are given. Change your model so that forward(idx, cache=None) takes an optional cache: attention appends each layer's new keys and values and attends over everything cached, and positions start at len(cache). Then write generate_cached(model, idx, max_new_tokens: int), which prefills the prompt once with model.forward(prompt, cache) and then feeds one token per step, and must return exactly what the given generate(idx, max_new_tokens: int) method returns. The prompt plus the new tokens must fit in block_size. (The function name and signature are this page's; sequences in a batch share positions.)

Reported variations

  • Two bug sets are described in detail (the second is a variant, not graded here), and one candidate says there are at least three variants. Most reports that name their bugs describe the four above, some naming only part of the set; two got the positional-embedding init, the mask, an output-projection shape bug (the nn.Linear dimensions, in one), and a missing gradient step (loss.backward(), in one). One counted five bugs, and two more said four or five.
  • Eight candidates got a different follow-up (fourteen got the cache): turn the model into a classifier. The prediction and the loss both change; one interviewer preferred taking the mean over tokens before the logits, and in one report the classifier decided whether the input numbers were odd or even.
  • One candidate was first asked the time complexity of generate() and how to improve it, then asked for the cache.

Follow-up Arc

Interviewers escalate through these phases. The order varies, but most candidates see at least one from each bucket.
Trade-off discussion · 3
Trade-off discussion

What is the time complexity of generate(), and how would you make it faster?

Probes for: before the KV cache is requested

Implement a KV cache: the KV and Cache classes are given; update attention and the positional offset and write your own generate.

Probes for: after the bugs are fixed

Turn the model into a classifier by changing the last layer; make the given test pass.

Probes for: instead of the KV cache, in eight reports

Approach Trade-offs

Approaches actually attempted in reports — including ones that lost candidates time. Pick deliberately.
ApproachNotes
Fix inside the marked regionsThe interviewer knows where each bug is and can follow a fix made there; the provided train and sample functions then show whether the loss converges.
Compare against a memorised nanoGPTFast when the architecture is familiar; one candidate says knowing nanoGPT is basically enough.
Masking rule for the cacheOne report's rule: apply the causal mask only while the cache is empty, checked before appending.

What Reports Emphasize

Common mistakes: Leaving the loss unshifted because you are thinking masked-LM rather than next-token prediction.; Replacing the learnable positional embedding with sin/cos instead of fixing its initial value.; Reading the driver code as well as the marked regions; the candidate who did said it did not help.; Passing over the typo in the attention output: one candidate said it took extra time to spot.; Running the code too often: CoderPad ran PyTorch very slowly for one candidate.; Finishing the cache with no time left to run it.

Interviewer hints: The interviewer knows where the bugs are and will say where and how many, but each bug has several valid fixes, so if you fix one a different way they may not be sure how to help. For the cache, the check is that its output matches the version without it. For the classifier, one interviewer preferred mean pooling before the logits.

What passers do: One candidate who passed the technical rounds read every post about the round, hand-wrote the main transformer structure, practised on bugs planted by an LLM, and then found the four bugs quickly. Another says knowing nanoGPT is basically enough, and a third that one practice run of the simplest GPT with a KV cache and decoding covers the follow-up.

Practice

Write your own against 7 test cases, or read the worked solution — approach, complexity, and code that runs.

Prepping for OpenAI with friends?

Send them this page. It is free to read, no account needed.

More OpenAI Questions

Free preview

Every question in the OpenAI catalog gets this depth

What you just read — canonical solution, follow-up arc, what passing candidates actually did — exists for all 91 OpenAI questions, refreshed monthly from new candidate reports.

$59/mo — or $50/mo with the 3-month pass · cancel anytime
OpenAI · Coding · Reported 35× across candidate reports
Is this helpful?