Prompt Tuning › Prompt Length Analysis

Michael BrenndoerferDecember 8, 20255 min read
Language AI HandbookAll chapters
Part 35 of 67Parameter-Efficient Fine-tuning
Chapter 263Prompt Tuning › Prompt Length Analysis
Reading section 9 of 13 · Prompt Length Analysis · 5 minSection 9 of 13 · 5 min

Book contents

Section 9 of 13 · 5 min read

Prompt Tuning › Prompt Length AnalysisOne section · Sections in this chapter9 / 13 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Let's empirically examine how prompt length affects optimization on our sentiment task by training models with different prompt lengths under the same deterministic mini-batch protocol. This controlled comparison shows where extra prompt capacity helps on a deliberately small, simple dataset and where its benefit plateaus.

In[22]:
Code
prompt_lengths = [1, 5, 10, 20, 50, 100]
final_losses = []
convergence_speeds = []  # Epochs to reach loss < 0.3

for p_len in prompt_lengths:
    # Reset before construction so every prompt length starts from a
    # reproducible vocabulary sample and the same pretrained checkpoint.
    torch.manual_seed(42)
    base_model_temp = AutoModel.from_pretrained(model_name)
    model_temp = PromptTuningClassifier(
        pretrained_model=base_model_temp,
        tokenizer=tokenizer,
        num_prompt_tokens=p_len,
        num_classes=2,
        init_from_vocab=True,
    )

    # Reset the classifier separately so its initial weights do not depend on
    # how many random vocabulary rows the prompt initializer sampled.
    torch.manual_seed(43)
    model_temp.classifier.reset_parameters()
    optimizer = torch.optim.AdamW(
        model_temp.parameters(), lr=3e-4, weight_decay=0.01
    )

    model_temp.train()
    convergence_epoch = None
    epoch_loss = None

    for epoch in range(50):
        batch_losses = []
        for i in range(0, len(texts), batch_size):
            optimizer.zero_grad()
            logits = model_temp(
                input_ids[i : i + batch_size],
                attention_mask[i : i + batch_size],
            )
            loss = F.cross_entropy(logits, labels_tensor[i : i + batch_size])
            loss.backward()
            optimizer.step()
            batch_losses.append(loss.item())

        # Compare prompt lengths using the same full-dataset epoch loss as the
        # chapter's main training loop, rather than one arbitrary first batch.
        epoch_loss = float(np.mean(batch_losses))
        if convergence_epoch is None and epoch_loss < 0.3:
            convergence_epoch = epoch + 1

    final_losses.append(epoch_loss)
    convergence_speeds.append(
        convergence_epoch if convergence_epoch is not None else 50
    )
Out[23]:
Visualization
Bar chart of final training loss for prompt lengths 1 through 100 tokens, colored red or green by convergence success.
Final training loss by soft prompt length (1 to 100 tokens) for binary sentiment classification. Every configuration reaches loss below 0.1 under the shared mini-batch protocol. The 1-token prompt finishes near 0.04, while prompt lengths from 5 to 100 finish below 0.005, showing a clear initial capacity gain followed by a plateau on this simple repeated dataset.
Bar chart of epochs to reach loss below 0.3 for prompt lengths 1 through 100 tokens.
Epochs required to first reach training loss below 0.3, by prompt length. The 1-token prompt takes 14 epochs, while prompt lengths from 5 to 100 all reach the threshold in 11 epochs. Extra prompt capacity therefore improves early optimization over a single token here, but additional length beyond 5 tokens does not change threshold time on this simple task.

All prompt lengths converge on this small repeated sentiment dataset, so the experiment does not establish a universal minimum prompt length. The 1-token configuration converges three epochs later and ends with a visibly higher loss than the others. Increasing the prompt to 5 tokens removes most of that gap; lengths from 5 through 100 behave almost identically. The useful conclusion is the plateau itself: extra prompt capacity can help initially, but once the task's limited complexity is represented, more virtual tokens add parameters and consume context without improving this training objective.

Parameter Efficiency Across Prompt Lengths

In[24]:
Code
embedding_dim = 768
classifier_params = 768 * 2 + 2
# Use the base model loaded earlier to get exact count
base_model_params = sum(p.numel() for p in base_model.parameters())

efficiency_results = []
for p_len in prompt_lengths:
    prompt_params = p_len * embedding_dim
    total_trainable = prompt_params + classifier_params
    efficiency = (total_trainable / base_model_params) * 100
    efficiency_results.append((p_len, total_trainable, efficiency))
Out[25]:
Console
Parameter count by prompt length:

    1 tokens: 2,306 params (0.0035% of model)
    5 tokens: 5,378 params (0.0081% of model)
   10 tokens: 9,218 params (0.0139% of model)
   20 tokens: 16,898 params (0.0255% of model)
   50 tokens: 39,938 params (0.0602% of model)
  100 tokens: 78,338 params (0.1180% of model)
Out[26]:
Visualization
Bar chart showing trainable parameter count for soft prompt lengths of 1 through 100 tokens, with percentage of total model annotated above each bar and a callout noting that full fine-tuning updates about 66 million parameters.
Trainable parameter count by soft prompt length for DistilBERT (approximately 66M total parameters). Even the largest 100-token prompt requires training only 76,800 parameters, representing 0.12% of the total model. The linear scaling relationship and tiny percentages illustrate why prompt tuning lets storing hundreds of task-specific adaptations in the space required for one full model copy.

Even with 100 prompt tokens, we are training less than 0.12% of the model's parameters. This extreme parameter efficiency is what makes prompt tuning attractive for scenarios with limited compute or when maintaining many task-specific adaptations. The entire parameter budget for 1,000 different 100-token tasks would be roughly 76.8 million parameters, comparable to storing one additional small base model rather than 1,000 full model copies.