← Microsoft Interview Insights

Microsoft·Machine Learning Engineer·Technical Phone Screen·Intermediate

Intermediate
Jun 2026

Summary

Microsoft ML engineer coding round, basically a PyTorch implementation exercise where you fill in blanks to build a tiny next-token prediction model. Pretty hands-on, less theory and more 'can you actually write the code.'

Questions Asked (4)

Q1

Implement a small next-token prediction model in PyTorch using the architecture: Embedding -> Linear -> ReLU -> Linear. Fill in the missing pieces including the DataLoader setup, model layer definitions, and the forward method.

Technical Trade-offsAlgorithms & Data Structures
Author's notes

The architecture itself wasn't the hard part.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the task: next-token prediction with a simple Embedding -> Linear -> ReLU -> Linear architecture. Then walk through the implementation step-by-step: dataset and DataLoader setup, model definition with proper dimensions, and the forward pass. Emphasize shape transformations and the importance of matching output dimensions to vocabulary size.

Pro tip: Mention that the model outputs logits, so you should use CrossEntropyLoss which combines LogSoftmax and NLLLoss, and ensure the target is a 1D tensor of token indices. Also, note that the embedding dimension and hidden dimension are hyperparameters, but the output dimension must equal the vocabulary size.

1. Clarify the task and data

Confirm that the input is a sequence of token indices and the target is the next token index. Define the vocabulary size and sequence length.

2. Set up Dataset and DataLoader

Create a Dataset that returns (input_sequence, target_token) pairs, and wrap it in a DataLoader with appropriate batch size and shuffling.

3. Define the model layers

In __init__, define nn.Embedding(vocab_size, embed_dim), nn.Linear(embed_dim, hidden_dim), nn.ReLU(), and nn.Linear(hidden_dim, vocab_size).

4. Implement the forward method

In forward, pass input through embedding, then linear, ReLU, and final linear. Ensure the output shape is (batch_size, vocab_size) by taking the last time step if needed.

5. Discuss training and loss

Mention using CrossEntropyLoss and an optimizer like Adam. Highlight that the model outputs logits and no softmax is needed before the loss.

Key Points to Mention

  • Embedding layer maps token indices to dense vectors of size embed_dim.
  • The first Linear layer projects from embed_dim to hidden_dim, followed by ReLU activation.
  • The final Linear layer projects from hidden_dim to vocab_size to produce logits for each token in the vocabulary.
  • DataLoader batches sequences and targets; use shuffle=True for training.
  • CrossEntropyLoss expects logits and target indices, not one-hot vectors.
  • For next-token prediction, the target is the token following the input sequence; if using a sliding window, ensure proper alignment.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

Given a batch of sequences, how do you prepare the inputs and targets for next-token prediction before passing them into the model?

Algorithms & Data StructuresSystem Design
Author's notes

This is the kind of thing that seems obvious in retrospect.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by framing the problem as a shift-by-one alignment task: inputs are tokens 0..n-1 and targets are tokens 1..n. Then walk through the concrete pipeline: tokenization, padding/truncation, creating shifted sequences, and masking padding labels so they don't contribute to the loss.

Pro tip: Mention that you typically set padding token labels to -100 (or ignore_index) so the loss ignores them, and that for causal models you also need a causal attention mask to prevent attending to future tokens.

1. Tokenize and batch sequences

Convert raw text into token IDs using the model's tokenizer, then group sequences into a batch. Handle variable lengths via padding or truncation to a fixed max length.

2. Create shifted input-target pairs

For each sequence of tokens [t0, t1, ..., tn], set input = [t0, t1, ..., t_{n-1}] and target = [t1, t2, ..., tn]. This ensures each position predicts the next token.

3. Apply padding and attention masks

Pad inputs to the same length within the batch, and create an attention mask (1 for real tokens, 0 for padding). For causal models, also apply a causal mask to prevent attending to future tokens.

4. Mask padding in the loss

Set target labels for padding positions to -100 (or the framework's ignore index) so they are excluded from the cross-entropy loss. This prevents the model from learning to predict padding.

5. Verify alignment and shapes

Double-check that input and target sequences are correctly shifted and have the same shape. Ensure masks are correctly aligned with the sequences before feeding into the model.

Key Points to Mention

  • Shift-by-one alignment: inputs and targets are offset by one token.
  • Padding and truncation to handle variable-length sequences in a batch.
  • Attention masks to ignore padding tokens and causal masks for autoregressive models.
  • Label masking (e.g., -100) to exclude padding from loss computation.
  • Batch shape consistency: input_ids, attention_mask, and labels must align.
  • Efficiency considerations: packing sequences or using dynamic padding to reduce wasted computation.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

After slicing inputs and targets from the sequence batch, how do you reshape them so all token positions are treated as a single flat batch before computing the loss?

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

Flatten the token positions into one batch dimension before CrossEntropyLoss.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Explain that after slicing inputs and targets from the sequence batch, you flatten the batch and sequence dimensions using a view or reshape operation, such as inputs.view(-1, vocab_size) and targets.view(-1). This treats every token position as an independent example, allowing the loss function to compute a single scalar loss over all tokens.

Pro tip: Mention that using view(-1) is efficient because it avoids copying data when the tensor is contiguous, and note that ignoring padding tokens via ignore_index is crucial to avoid skewing the loss.

1. Slice inputs and targets

Extract the input and target tensors from the sequence batch, ensuring they have shape (batch_size, seq_len) or (batch_size, seq_len, features).

2. Flatten batch and sequence dimensions

Use .view(-1, ...) or .reshape(-1, ...) to collapse the batch and sequence dimensions into a single dimension, resulting in shape (batch_size * seq_len, ...).

3. Compute loss on flattened tensors

Pass the flattened inputs and targets to the loss function (e.g., CrossEntropyLoss) to compute a single loss value over all token positions.

4. Handle padding if necessary

If the sequence contains padding tokens, use ignore_index in the loss function to exclude them from the loss calculation.

Key Points to Mention

  • Flattening with view(-1) or reshape(-1) to merge batch and sequence dimensions
  • Ensuring tensors are contiguous before using view, or using reshape to handle non-contiguous tensors
  • Using ignore_index to mask padding tokens in the loss function
  • The loss function (e.g., CrossEntropyLoss) expects input of shape (N, C) and target of shape (N)
  • Efficiency benefits of flattening: vectorized computation and reduced overhead
  • Common pitfalls: forgetting to flatten, leading to incorrect loss reduction or shape mismatches

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

Complete a training loop: run the forward pass, compute CrossEntropyLoss, backpropagate, and step the Adam optimizer.

Algorithms & Data Structures
Author's notes

Routine stuff.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by outlining the standard PyTorch training loop structure, emphasizing the correct order of operations: zero gradients, forward pass, loss computation, backward pass, and optimizer step. Then, walk through each step with a concrete code example, explaining the purpose and common pitfalls. Finally, mention best practices like using model.train(), moving data to device, and handling gradients.

Pro tip: Always call optimizer.zero_grad() before the backward pass to prevent gradient accumulation, and consider using torch.nn.utils.clip_grad_norm_ if you encounter exploding gradients. Also, ensure the model is in training mode with model.train() to enable dropout and batch normalization updates.

1. Set up model and optimizer

Instantiate the model, define the loss function (CrossEntropyLoss), and create the Adam optimizer with model parameters and learning rate. Ensure the model is in training mode.

2. Zero gradients

Call optimizer.zero_grad() to clear any previously accumulated gradients. This is crucial because PyTorch accumulates gradients by default.

3. Forward pass and loss computation

Pass the input batch through the model to get predictions, then compute the loss using CrossEntropyLoss between predictions and target labels.

4. Backward pass

Call loss.backward() to compute gradients of the loss with respect to all model parameters via backpropagation.

5. Optimizer step

Call optimizer.step() to update the model parameters using the computed gradients and the Adam update rule.

Key Points to Mention

  • Order of operations: zero_grad, forward, loss, backward, step
  • CrossEntropyLoss combines LogSoftmax and NLLLoss, suitable for multi-class classification
  • Adam optimizer maintains per-parameter learning rates and momentum estimates
  • Gradient accumulation and the need to zero gradients each iteration
  • Model training mode (model.train()) vs evaluation mode (model.eval())
  • Device placement: ensure model and data are on the same device (CPU/GPU)

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.