M01 · LLM foundations and evaluation basics01-0320 min read

Lesson 8 of 106 · Module 2 of 14 · Week 1

Threads:The measurement threadThe weights threadThe core-concepts thread

Tensor Shapes in Transformers: Batch, Sequence, and Hidden Size

Data moves through a transformer as a three-dimensional tensor shaped (batch, sequence, hidden) — how many texts at once, how many tokens each, and how many numbers represent each token. Every layer in the stack consumes that shape and returns it unchanged, which is why the triple is the single vocabulary you need to read a model config, a memory estimate, or a shape-mismatch error.

01

What the (batch, sequence, hidden) tensor shape is

Identity statement: a tensor is an n-dimensional array of numbers, and the tensor carrying text through a transformer is 3-D with axes (batch, sequence, hidden).

AxisCommon namesWhat it countsSet by
BatchB, batch_size, NIndependent sequences processed togetherYou, at runtime
SequenceS, T, seq_len, context_lengthTokens in each sequenceThe input, capped by the model's context window
HiddenH, d_model, hidden_size, dNumbers representing one tokenThe model architecture — fixed

When it matters: every time you read a model card, size a deployment, interpret a shape error, or reason about why a longer prompt costs more.

The critical asymmetry: hidden size is a property of the trained model and cannot be changed, while batch and sequence vary per request. A model with a hidden size of 4,096 has that hidden size forever; you cannot serve it "at 2,048" without retraining. But you choose the batch, and the caller's input determines the sequence length.

Rank, shape, and dimension — three words that are not synonyms

Shape talk goes wrong when these three get swapped, and they are swapped constantly in casual writing.

WordMeansExample on (8, 512, 4096)
Rank (or "number of dimensions", ndim)How many axes the tensor has3
ShapeThe length of every axis, in order(8, 512, 4096)
DimensionAmbiguous in English — either an axis, or the length of one"the hidden dimension" = axis 2, "4,096 dimensions" = its length
SizeTotal element count, the product of the shape8 × 512 × 4096 = 16,777,216

Because "dimension" carries both meanings, prefer axis when you mean the slot and width or length when you mean the count. "A 4,096-dimensional embedding" is the width sense; "reduce along the sequence dimension" is the axis sense.

A vocabulary ladder is worth having too, because the exam and the literature both use the lower-rank names freely:

RankNameShape exampleWhere you meet it here
0Scalar()A loss value
1Vector(4096,)One token's embedding
2Matrix(512, 4096)One sequence's embeddings; also every weight matrix
33-D tensor(8, 512, 4096)The residual stream — the shape of this lesson
44-D tensor(8, 32, 512, 512)Attention scores, once heads are split out
02

How the tensor shape changes as data moves through a transformer

L1 — The one-sentence picture

A transformer is a stack of identical-shaped rooms. Text enters as integers, the embedding layer turns each integer into a row of numbers, that block of numbers walks through every layer coming out the same shape it went in, and only at the very end does the shape change — into one score per possible next token.

If you only remember that, you can answer the shape-adjacent items. Everything below makes it precise.

L2 — The end-to-end trace

Follow one request end to end. Take a batch of 2 texts, 10 tokens each, through a model with hidden size 4,096 and vocabulary 32,000.

text
raw text            "The capital of France is..."
tokenize        →   (2, 10)              integer token ids, no hidden axis yet
embedding       →   (2, 10, 4096)        each id becomes a 4096-vector
+ positional    →   (2, 10, 4096)        shape unchanged
attention block →   (2, 10, 4096)        shape unchanged
feed-forward    →   (2, 10, 4096)        shape unchanged
... × N layers  →   (2, 10, 4096)        shape unchanged
output head     →   (2, 10, 32000)       hidden axis becomes vocabulary scores

Three things to take from that trace.

The embedding layer is where the hidden axis is born. Before it you have integers — token ids, shape (batch, sequence). After it you have vectors. This is the conversion of text to numbers that the whole field rests on.

The residual stream is shape-invariant. Every transformer block takes (B, S, H) and returns (B, S, H). That is not an accident of implementation; it is what makes the blocks stackable, and it is what lets residual connections add a block's output back to its input. When you read "24 layers," it means this identical shape passed through 24 times.

Only the last step changes the final axis, projecting hidden size to vocabulary size so you get one score per possible next token — the distribution from 01-01. Note where the next-token prediction lives: at the last sequence position of that output. During generation you read row (b, S-1, :) and discard the rest.

L2 — Where the third axis splits for multi-head attention

Inside attention, the hidden axis is temporarily reshaped into heads: (B, S, H) becomes (B, heads, S, H/heads). With H = 4,096 and 32 heads, each head works in 128 dimensions. Then the heads are concatenated back to (B, S, H). You need to recognise this so a 4-D tensor in a diagram does not surprise you. You do not need to reproduce the attention arithmetic — candidate reports consistently name detailed attention math as depth that did not appear on the exam.

The reshape is worth one more sentence because it explains a config constraint you will see enforced: hidden size must be divisible by head count. 4096 / 32 = 128 works; a hypothetical 4,096 with 30 heads does not, and a library will refuse it. When a config fragment lists both numbers, dividing them tells you the per-head width immediately.

L3 — The scaling consequence you can predict from the shape alone

The shape tells you the cost. Activation memory scales with batch × sequence × hidden, so it is linear in each. But attention compares every token to every other token, producing an intermediate of shape (B, heads, S, S)quadratic in sequence length.

That single asymmetry explains a family of exam-adjacent facts: why doubling the batch roughly doubles memory, why doubling the prompt length can roughly quadruple the attention term, why context windows were historically small and expensive to extend, and why long-context efficiency is an active engineering problem rather than a config flag.

Make it concrete with an illustrative construction. Take B = 1, 32 heads, hidden 4,096, and compare two sequence lengths:

text
S = 512     residual stream   1 × 512 × 4096      =      2.10M values
            attention scores  1 × 32 × 512 × 512  =      8.39M values

S = 2048    residual stream   1 × 2048 × 4096     =      8.39M values   (4× — linear)
            attention scores  1 × 32 × 2048 × 2048 =   134.2M values    (16× — quadratic)

Quadruple the sequence length: the residual stream grows fourfold, the attention score term grows sixteenfold. That is the whole story of why long context is expensive, and it fell out of reading shapes rather than from any measurement. (Production attention kernels avoid materialising that full S × S block, which is exactly why such kernels exist — but the compute the shape implies does not go away.)

This lesson stops at L3 on purpose. You will not be asked to write the reshape, tune a kernel, or derive attention complexity formally. Reading a shape and predicting a cost direction is the whole ask.

03

Batch vs sequence vs hidden vs vocabulary vs layers — the confusables table

Every one of these is a number in a model config, and every pair of them gets confused by someone. This table is the highest-value asset on the page.

QuantityWhat it countsTypical valueWho sets itChanging it costs
Batch sizeSequences processed together1–256You, per request or per server configMemory, linearly; per-request latency
Sequence lengthTokens in one sequence1 to the context capThe caller's inputMemory linearly, attention quadratically
Context windowThe maximum legal sequence length4k–128k+The model, fixedCannot change without a different model or variant
Hidden sizeNumbers per token in the residual stream768–8192The architecture, fixedRetraining from scratch
Head countAttention subspaces12–64The architecture, fixedRetraining; must divide hidden size
Layer countShape-preserving blocks in the stack12–80The architecture, fixedRetraining
Vocabulary sizeDistinct tokens the tokenizer knows32k–256kThe tokenizer, fixed with the modelA new tokenizer and retraining
Embedding dimension (of an embedding model)Numbers in the output vector384–3072That model, fixedA different embedding model, and re-indexing everything

Two rows are worth reading against each other. Sequence length and context window are the same axis, one actual and one maximum — configs list the maximum as max_position_embeddings, and exceeding it truncates or errors. Hidden size and embedding dimension are the same kind of quantity in different products: a generative model's hidden size is internal and you never see it, while an embedding model's output dimension is the thing you must match to your vector index forever.

04

Worked example: reading a config and predicting a shape

Here is a config fragment of the kind you meet on any model hub:

text
hidden_size:            4096
num_hidden_layers:      32
num_attention_heads:    32
max_position_embeddings: 4096
vocab_size:             32000

Read it off:

  • Hidden size 4,096 — each token is a 4,096-number vector throughout the stack. Fixed forever.
  • 32 layers — the (B, S, 4096) tensor passes through 32 shape-preserving blocks.
  • 32 heads — attention splits into 32 subspaces of 128 dimensions each (4,096 ÷ 32).
  • max_position_embeddings 4,096 — the sequence axis cannot exceed 4,096 tokens. This is the context window, and it is a different number from the hidden size that happens to match here. Conflating them is a real and easy error.
  • vocab_size 32,000 — the output head produces 32,000 scores per position.

Now predict. You send a batch of 8 requests of 512 tokens each. The tensor entering layer 1 is (8, 512, 4096). The tensor leaving layer 32 is (8, 512, 4096). The logits are (8, 512, 32000), and for generation you care about (8, 4096) — the last position of each sequence, projected. If someone sends a 5,000-token prompt, it fails or is truncated, because 5,000 exceeds the sequence cap. None of that required running anything.

One more prediction from the same config, because it is the one people find surprising. How big is the logits tensor for that batch?

text
logits = 8 × 512 × 32000 = 131,072,000 values
at 2 bytes each (BF16)   ≈ 262 MB

A quarter of a gigabyte of scores, of which — during generation — you use 8 rows. That waste is the direct motivation for the implementation trick of only projecting the final position, and it is a nice demonstration that shapes tell you where the cost is before you profile anything.

05

Worked example: the shapes that make a shape-mismatch error readable

Shape errors are the most common failure you will hit doing this work, and they are readable once you know which axis the library is complaining about. Here are the four archetypes, written as an illustrative reconstruction rather than a quote from any specific library version:

What you didThe error's shape signatureThe axis at faultFix
Fed token ids straight into a transformer blockexpected 3 dimensions, got 2Missing hidden axisRun them through the embedding layer first
Passed one sequence where a batch was expectedexpected (B, S), got (S,)Missing batch axisAdd a leading batch axis of size 1
Concatenated two batches with different token countssizes do not match at dimension 1Sequence axis mismatchPad to a common length and pass an attention mask
Loaded an adapter trained on a different base modelmat1 and mat2 shapes cannot be multiplied (…×4096 and 5120×…)Hidden axis mismatchThe adapter's hidden size must match the base's

The reading habit that turns all four into thirty-second fixes: name the axis, then name where it should have come from. Axis 0 is batch and comes from how you assembled the request. Axis 1 is sequence and comes from the tokenizer. Axis 2 is hidden and comes from the model config. If the number in the error is a vocabulary-sized number, you are past the output head; if it is a small power of two times a hundred-ish, you are looking at a per-head width.

Padding deserves its own note because it is the practical reason batches are annoying. A batch must be rectangular — every sequence in a (B, S, H) tensor has the same S. Real requests do not. So short sequences are padded to the longest one in the batch and an attention mask marks which positions are real, so the padding cannot influence the result. Two consequences: batching wildly different lengths wastes compute on padding, and length-bucketing requests is a standard throughput optimisation.

06

Where the shape changes on purpose: embeddings, classification, and the KV cache

The shape-preserving rule holds inside the stack. It stops holding at three boundaries you will meet constantly.

Embedding models collapse the sequence axis. A text embedding model reads (B, S, H) and returns (B, H) — one fixed-length vector per input text, regardless of how many tokens went in. That collapse is called pooling, and it is why a two-word query and a 400-word paragraph produce vectors of the same length and can be compared at all. That comparison is 01-04, and the vector-database lessons depend on it entirely. The three pooling styles you should be able to name: mean pooling over positions, taking a designated [CLS]-style position, and last-token pooling — all doing the same job of turning a variable-length matrix into one vector.

Classification heads collapse to class count. An encoder-only classifier goes (B, S, H) → pool → (B, H) → head → (B, C) for C classes. Sentiment with three classes returns (B, 3). Note the family resemblance to the generative output head, which is just the same move with C = vocabulary size.

The KV cache is a fourth shape entirely. During generation, keys and values from previous positions are cached so they need not be recomputed. Its shape is roughly (layers, 2, B, heads, S, H/heads) — the 2 being keys and values. What you should take from that is not the exact ordering but the multiplication: the KV cache grows with layers × batch × sequence length, which is why long conversations and large batches, not big weight files, are usually what exhausts a serving GPU's spare memory. The weights are a fixed cost from 01-02; the KV cache is the variable one.

BoundaryShape inShape outWhich axis moved
Tokenizertext(B, S)Sequence created
Embedding layer(B, S)(B, S, H)Hidden created
Transformer block(B, S, H)(B, S, H)None
Head split (inside attention)(B, S, H)(B, heads, S, H/heads)Hidden split, then rejoined
Attention scores(B, heads, S, d)(B, heads, S, S)Hidden replaced by sequence — the quadratic term
Pooling (embedding model)(B, S, H)(B, H)Sequence collapsed
Classification head(B, H)(B, C)Hidden → classes
LM output head(B, S, H)(B, S, V)Hidden → vocabulary
07

Why tensor shapes are on the NCA-GENL exam

Tensor shapes serve objectives 1.5 (ML fundamentals) and 1.10 (using Python packages such as NumPy and Keras to implement analyses) — you cannot use NumPy meaningfully without shape fluency. Core ML is 30% of the blueprint.

You will almost certainly not see an item that says "what is the shape of the residual stream." You will see items where the shape is the reason the answer is the answer:

  • Why a longer context costs disproportionately more (quadratic attention term).
  • Why batch size is a throughput lever and hidden size is not a lever at all.
  • Why an embedding model outputs a fixed-length vector regardless of input length — a pooled (B, H), with the sequence axis collapsed.
  • Why increasing batch size raises throughput but also raises per-request latency.
  • Why you cannot swap in an embedding model with a different output dimension without re-indexing your corpus.

How the question tends to be phrased

Two shapes recur. The first is a lever question: "throughput on a serving endpoint is too low; which change is most likely to help?" — where the keyed answer is the runtime lever (batch size, or batching strategy) and the distractors offer architecture numbers you cannot change without retraining. The second is a cost-direction question: "a team doubles the average prompt length; what happens?" — where the keyed answer is that cost grows faster than linearly because of attention, and the distractors offer "unchanged," "doubles exactly," or "depends only on output length."

What the distractors typically look like

Expect hidden size offered as something you tune per request; context window offered as a fix for a model not knowing something (an empty bigger window changes nothing — that is the 01-02 point); vocabulary size offered where hidden size belongs; and "reduce the number of layers" offered as a serving-time option, which it is not for a given checkpoint.

Calibration, not fact: candidate reports describe the exam as general-level and specifically name deep attention math as depth that did not appear. NVIDIA publishes no item-level detail. So treat this lesson as enabling rather than tested. Its value is that four or five later answers stop requiring memorisation once you can see the shape.

08

Common mistakes with batch, sequence, and hidden size

MistakeSymptom you would actually observeFix
Confusing hidden size with context windowYou claim a model can read 4,096 tokens because its hidden size is 4,096Hidden is the width of one token's vector; context is how many tokens fit. Read max_position_embeddings
Confusing hidden size with vocabulary sizeYour logits-memory estimate is off by a large factorThey meet only at the output head; hidden is per-token width, vocabulary is token count
Expecting the shape to shrink layer by layerYou cannot explain how residual connections add anythingTransformer blocks are shape-preserving; CNN intuition does not transfer
Assuming batch size is freeThroughput improves, then p99 latency and memory both blow upBatch multiplies activations and KV cache linearly and raises per-request latency
Treating attention cost as linear in sequence lengthYou budget for 2× and get hit with far moreThe (B, heads, S, S) term is quadratic — the most consequential shape fact here
Forgetting that generation reads only the final positionYou cannot explain what KV caching removesAll other positions' logits are computed and discarded in a plain forward pass
Ignoring padding and the attention maskBatched results differ from single-request results on short inputsBatches are rectangular; padded positions must be masked out
Assuming two embedding models are interchangeableSimilarity scores become meaningless after a model swapOutput dimension and vector space are both model-specific; changing either forces a full re-index
09

Does batch size change the model's output?

For a correct implementation, no — batching is a throughput arrangement, not a semantic one. Each sequence in a batch is processed independently; nothing in a transformer lets row 3 attend to row 5.

Two honest caveats, both worth knowing because they cause real confusion. First, floating-point arithmetic is not perfectly associative, so different batch sizes can take different kernel paths and produce results that differ in the last bits. That is numerical noise, not a behaviour change, though it can make "identical" runs fail an exact-match test. Second, if padding is not masked correctly, batch composition genuinely does change the answer — which is a bug, and one that only appears when you batch inputs of different lengths.

The practical rule: batch size is a cost and latency lever. If a scenario claims batching changed the meaning of a response, suspect masking.

10

Why can't you just increase the hidden size to make a model smarter?

Because hidden size is baked into every weight matrix in the checkpoint. Every attention projection is a d × d matrix and every feed-forward matrix is d × 4d; change d and none of the stored numbers have the right shape any more. There is no operation that "widens" a trained model — you would be initialising a new, differently shaped model and training it from scratch.

This is the concrete reason for the architecture-versus-runtime split in section 3. Hidden size, layer count, head count, and vocabulary are decisions frozen at pretraining. Batch size, sequence length used, and precision are the things you actually control at deployment. When an exam scenario asks what a deployment team can change, the answer lives in the runtime column.

11

Why does an embedding model return the same-length vector for any input?

Because pooling collapses the sequence axis. The model still builds (B, S, H) internally — a 3-token query produces 3 hidden vectors, a 300-token paragraph produces 300 — and then reduces along the sequence axis to a single (B, H) vector per text.

That is not a detail; it is what makes semantic search possible. Two texts of wildly different length end up as two vectors of identical length in the same space, and identical length is the precondition for taking a dot product or a cosine between them. It also explains a known limitation: squeezing a long document into one fixed-length vector loses detail, which is exactly why RAG pipelines chunk documents before embedding them rather than embedding a whole document at once.

12

Glossary recap: the terms this lesson introduced

TermOne-line definition
TensorAn n-dimensional array of numbers
Rank / ndimHow many axes a tensor has
ShapeThe ordered lengths of all axes, e.g. (8, 512, 4096)
Batch (B)Number of independent sequences processed together; a runtime choice
Sequence length (S)Number of tokens in a sequence; set by the input
Context windowThe maximum legal sequence length, fixed by the model (max_position_embeddings)
Hidden size (H, d_model)Numbers representing one token in the residual stream; fixed by architecture
Residual streamThe shape-preserving (B, S, H) tensor passed from block to block
Shape-preservingProperty of a transformer block: same shape in, same shape out
Head splitTemporary reshape of hidden into (B, heads, S, H/heads) inside attention
Output head / unembeddingThe projection from hidden size to vocabulary size
LogitsThe (B, S, V) pre-softmax scores produced by the output head
PaddingFiller tokens making a batch rectangular
Attention maskThe marker telling the model which positions are real rather than padding
PoolingCollapsing the sequence axis to produce one vector per text
KV cacheCached attention keys and values, growing with layers × batch × sequence
13

Key takeaways on tensor shapes in transformers

  • Text flows as (batch, sequence, hidden): how many texts, how many tokens, how many numbers per token.
  • Hidden size is fixed by the architecture. Batch and sequence vary per request. That split decides what a deployment team can actually change.
  • Transformer blocks are shape-preserving: (B, S, H) in, (B, S, H) out, N times. That is what makes them stackable and what residual connections require.
  • The embedding layer creates the hidden axis; the output head replaces it with vocabulary scores.
  • Multi-head attention temporarily reshapes hidden into (B, heads, S, H/heads) and concatenates back; hidden size must be divisible by head count.
  • Memory is linear in batch and hidden but quadratic in sequence length through attention — the one cost fact worth carrying forward.
  • Pooling collapses the sequence axis to (B, H), which is what makes embeddings comparable across texts of any length.
  • The KV cache, not the weight file, is usually what consumes spare serving memory as conversations and batches grow.
14

Next: vectors, dot products, and cosine similarity

You can now say what shape a token's representation has. What you cannot yet do is compare two of those representations — and comparison is the operation underneath embeddings, semantic search, vector databases and retrieval scoring, which together account for a substantial slice of the exam.

Next: 01-04 Vectors, dot products, and cosine similarity — the one piece of linear algebra this course asks you to know airtight, because six later groups of lessons reduce to it.