Improving LLM Accuracy with Targeted Critiques
Listen to the summary
Uses a voice available on your device
Audio options
On this page 5 sections
Related concepts 6 concepts
Key Takeaways
- CritICL-static achieves 59.2 percent accuracy on Qwen2.5-72B-Instruct, surpassing the 59.0 percent accuracy of the Consistency@5 baseline.
- The method reduces total token usage compared to standard test-time scaling, requiring 3768 tokens on MATH compared to 4192 to 7533 tokens for other scaling methods.
- The system relies on CritBank, a database of failure-mode critiques generated by smaller models within the same model family.
- Cross-family transfer of failure modes is significantly less effective than within-family transfer.
Summary & Methodology Analysis
CritICL optimizes model performance by prepending failure-aware critiques to the input prompt, which acts as a form of in-context learning where the model is guided by historical error patterns. The framework operates by constructing a CritBank, which contains CoT (Chain of Thought, a technique where models generate intermediate reasoning steps) responses and critiques sourced from smaller instruction-tuned models. For the Qwen family, this includes models like Qwen2.5-1.5B-Instruct, while the Llama family utilizes models such as Llama-3.2-1B-Instruct. By profiling these failure modes, the system retrieves relevant examples to prevent the target model from repeating specific reasoning mistakes.
Interactive System Flowchart
Illustrative Implementation
A short sketch of the paper's core idea, not the authors' own code.
# Illustrative sketch (not from the paper)
import torch
from typing import List, Dict
# Placeholder: load a small LLM that will generate critiques (CritBank construction)
small_model = torch.hub.load('huggingface/pytorch-transformers', 'model', 'qwen2.5-1.5B-Instruct')
# Placeholder: load the strong target model
target_model = torch.hub.load('huggingface/pytorch-transformers', 'model', 'Qwen2.5-72B-Instruct')
# ------------------------------------------------------------------
# 1. Failure‑mode profiling (static example – aggregate distribution)
# In practice this would be pre‑computed; here we mock it as a dict.
static_profile = {"arithmetic": 0.4, "algebra": 0.35, "geometry": 0.25}
# ------------------------------------------------------------------
# 2. Retrieve relevant critique examples from CritBank
def retrieve_critiques(predicted_modes: Dict[str, float], critbank: List[Dict], k: int = 5) -> List[str]:
"""Select up to *k* critiques whose labeled failure mode overlaps most with *predicted_modes*.
critbank entries are assumed to have keys: 'mode' and 'critique'."""
# Simple overlap scoring: sum of probabilities for matching mode
scored = []
for entry in critbank:
mode = entry["mode"]
score = predicted_modes.get(mode, 0.0)
scored.append((score, entry["critique"]))
# Sort descending and take top‑k non‑zero scores
scored.sort(reverse=True, key=lambda x: x[0])
return [c for s, c in scored[:k] if s > 0]
# ------------------------------------------------------------------
# 3. Targeted inference with retrieved critiques as in‑context examples
def generate_with_critiques(question: str, critiques: List[str]) -> str:
# Build prompt: prepend each critique as a separate example
prompt = "\n".join(critiques) + "\nQuestion: " + question + "\nAnswer:"
# Placeholder generation call – in reality use target_model.generate(...)
output = target_model.generate(prompt)
return output
# ------------------------------------------------------------------
# Mock CritBank (normally built offline from weak model CoT failures)
critbank = [
{"mode": "arithmetic", "critique": "Avoid assuming addition is commutative when signs differ."},
{"mode": "algebra", "critique": "Check that you distribute multiplication over addition correctly."},
{"mode": "geometry", "critique": "Remember that the sum of interior angles of a triangle is 180°."},
]
# Example usage
question = "What is the result of -3 + 5?"
# Use static profile as the predicted failure‑mode distribution for this input
critiques = retrieve_critiques(static_profile, critbank, k=5)
answer = generate_with_critiques(question, critiques)
print("Answer:", answer)
// Illustrative sketch (not from the paper)
const { pipeline } = require('@xenova/transformers'); // placeholder library
// Load a weak model for CritBank construction (mocked here)
const weakModel = await pipeline('text-generation', { model: 'qwen2.5-1.5b-instruct' });
// Load the strong target model
const targetModel = await pipeline('text-generation', { model: 'Qwen2.5-72B-Instruct' });
// ------------------------------------------------------------------
// 1. Static failure‑mode profile (pre‑computed distribution)
const staticProfile = { arithmetic: 0.4, algebra: 0.35, geometry: 0.25 };
// ------------------------------------------------------------------
// 2. Retrieve relevant critiques from CritBank
function retrieveCritiques(predictedModes, critBank, k = 5) {
// Score each critique by the probability of its failure mode
const scored = critBank.map(entry => {
const score = predictedModes[entry.mode] || 0;
return { score, critique: entry.critique };
});
// Sort descending and keep top‑k with non‑zero score
scored.sort((a, b) => b.score - a.score);
return scored.filter(item => item.score > 0).slice(0, k).map(item => item.critique);
}
// ------------------------------------------------------------------
// 3. Targeted inference – prepend critiques as in‑context examples
async function generateWithCritiques(question, critiques) {
const prompt = critiques.join('\n') + `\nQuestion: ${question}\nAnswer:`;
const result = await targetModel(prompt);
return result[0].generated_text;
}
// ------------------------------------------------------------------
// Mock CritBank (normally built from weak model CoT failures)
const critBank = [
{ mode: 'arithmetic', critique: 'Avoid assuming addition is commutative when signs differ.' },
{ mode: 'algebra', critique: 'Check that you distribute multiplication over addition correctly.' },
{ mode: 'geometry', critique: 'Remember that the sum of interior angles of a triangle is 180°.' },
];
// Example usage
(async () => {
const question = 'What is the result of -3 + 5?';
const critiques = retrieveCritiques(staticProfile, critBank, 5);
const answer = await generateWithCritiques(question, critiques);
console.log('Answer:', answer);
})();
Cross-Examination & FAQs
A deeper dive clarifying mechanics, constraints, and baseline evaluations.
Q1. What is the primary goal of CritICL?
The goal is to improve the accuracy of large language models by using structured failure mode data from smaller models to provide targeted guidance during inference.
Q2. How does this method impact model performance?
It improves overall accuracy, reaching 59.2 percent on Qwen2.5-72B-Instruct, which outperforms the Consistency@5 baseline.
Q3. Does this method increase the cost of running inference?
It reduces total token usage compared to test-time scaling methods, though it does incur a modest increase in input length due to the added critique examples.
Q4. How many tokens does CritICL-static typically use?
It requires 3768 total tokens per question on MATH, compared to the 4192 to 7533 tokens used by test-time scaling methods.
Q5. What is the difference between CritICL-static and CritICL-dynamic?
CritICL-static requires a single generation, while CritICL-dynamic requires two generations because of an additional failure-mode prediction step.
Q6. Can I use failure modes from one model family to improve another?
No, cross-family transfer of failure modes is significantly less effective than within-family transfer.
Q7. Which models were used to build the CritBank for the Llama family?
The CritBank for Llama was built using responses from Llama-3.2-1B-Instruct, Llama-3.2-3B-Instruct, and Llama-3.1-8B.
Q8. What is the main limitation regarding input length?
CritICL incurs a modest increase in input length because the system must include critique examples in the prompt.
Q9. Does the paper specify the exact memory footprint of this approach?
The paper does not specify the memory footprint.