Self-Instruct › Quality and Diversity Metrics
Language AI HandbookAll chapters Self-Instruct › Quality and Diversity MetricsOne section · Sections in this chapter10 / 14 ↓
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
Evaluating Self-Instruct outputs requires measuring both quality and diversity. A large dataset of repetitive instructions is no better than a small, diverse one. In fact, redundant data wastes computational resources during training and may cause the model to overfit to particular patterns. Several metrics help us understand whether our generation pipeline is creating useful training data, and they provide actionable signals for improving the pipeline when quality falls short.
The tension between scale and quality is a recurring theme in synthetic data generation. Self-Instruct makes it easy to generate hundreds of thousands of examples, but raw volume does not guarantee training value. A dataset of 100,000 near-identical sentiment classification examples will produce a model that performs well on sentiment classification and poorly on everything else. Measuring diversity across multiple dimensions, not just instruction count, is needed for understanding what a Self-Instruct dataset can teach a model.
Quality and diversity are not independent dimensions. High-quality instructions that are all variations on the same theme add diversity in name only. Diverse instructions that are poorly formed add variety in topic but fail to provide clear training signal. The best Self-Instruct datasets combine both: they are diverse in topic, task type, and output structure, and every individual instance is high quality in the sense that the instruction is clear, the input (when present) is relevant, and the output correctly responds to the instruction.
Tracking metrics over the course of a Self-Instruct run also reveals important dynamics. Diversity metrics typically peak in early iterations when the pool is small and every new instruction is novel, then gradually decline as the pool saturates and new instructions are increasingly variations on existing themes. Monitoring this trend helps you decide when to stop the generation process, adjust the filtering threshold, or inject new seed tasks to reopen the exploration frontier.
Diversity Metrics
Diversity can be measured at multiple levels, from individual word choices to overall structural patterns. Each metric captures a different aspect of what makes a dataset varied and complete:
def compute_diversity_metrics(tasks: List[Dict]) -> Dict:
"""
Compute diversity metrics for a task collection.
"""
instructions = [t["instruction"] for t in tasks]
# Vocabulary diversity
all_words = []
for inst in instructions:
all_words.extend(inst.lower().split())
vocab_size = len(set(all_words))
total_words = len(all_words)
type_token_ratio = vocab_size / total_words if total_words > 0 else 0
# Root word diversity (approximation via first word)
verb_starts = [inst.split()[0].lower() for inst in instructions if inst]
unique_verbs = len(set(verb_starts))
verb_diversity = unique_verbs / len(verb_starts) if verb_starts else 0
# Length diversity
lengths = [len(inst.split()) for inst in instructions]
length_std = (
sum((l - sum(lengths) / len(lengths)) ** 2 for l in lengths)
/ len(lengths)
) ** 0.5
return {
"vocabulary_size": vocab_size,
"type_token_ratio": type_token_ratio,
"unique_verb_starts": unique_verbs,
"verb_diversity": verb_diversity,
"avg_instruction_length": sum(lengths) / len(lengths),
"length_std": length_std,
}# Combine seed tasks with generated ones for analysis
all_tasks = seed_tasks + generated_batch
diversity_metrics = compute_diversity_metrics(all_tasks)Diversity Metrics: ---------------------------------------- vocabulary_size: 52 type_token_ratio: 0.693 unique_verb_starts: 8 verb_diversity: 0.800 avg_instruction_length: 7.500 length_std: 1.118
These metrics provide a quantitative view of the dataset's richness. A type-token ratio above 0.5 and high verb diversity suggest the instructions cover a wide range of actions and topics, rather than repeating the same few patterns. The length standard deviation indicates whether the dataset includes both short, focused instructions and longer, more detailed ones. Together, these measurements give a combined picture of diversity that helps guide further data generation or filtering decisions. When these metrics start declining over successive Self-Instruct iterations, it is a signal that the generation process is saturating and additional seed tasks or domain expansion may be needed.

Pairwise Similarity Distribution
The distribution of pairwise similarities reveals whether the dataset has clusters of similar instructions or maintains broad diversity. This analysis goes beyond simple metrics to show the actual structure of relationships within the dataset. A dataset where 80 percent of instruction pairs score near zero and only 5 percent score above 0.5 is much more diverse than one where pairs cluster around 0.4. The shape of the distribution, not just its mean, tells the story of dataset coverage.
Pairwise similarity analysis is particularly useful for diagnosing problems with the generation process. If the distribution shows a secondary peak near the filter threshold (0.7), it suggests that many nearly-duplicate instructions are entering the pool just under the rejection cutoff. Tightening the threshold or diversifying the seed tasks can address this issue. If the distribution shows an unusually large peak near 0.0, it might indicate that the model is generating instructions that are syntactically diverse but semantically similar, a subtler form of redundancy that ROUGE-L cannot detect.
def compute_pairwise_similarities(tasks):
"""
Compute all pairwise ROUGE-L similarities between instructions.
"""
instructions = [t["instruction"] for t in tasks]
similarities = []
for i in range(len(instructions)):
for j in range(i + 1, len(instructions)):
sim = compute_rouge_l(instructions[i], instructions[j])
similarities.append(sim)
return similaritiespairwise_sims = compute_pairwise_similarities(all_tasks)
A well-functioning Self-Instruct pipeline produces a left-skewed distribution where most instruction pairs have low similarity. This pattern indicates that the dataset contains many distinct instructions rather than variations on a few themes. The similarity threshold (typically 0.7) prevents the right tail from growing with near-duplicate instructions, maintaining the overall diversity of the pool.