ChemBench

repository·dev·Indexed 40 days ago

https://github.com/lamalab-org/chembench

A modular Python package (v0.3.0) for benchmarking the chemistry performance of large language models (LLMs) and multimodal vision-language models. It provides tools for running evaluations via ChemBenchmark and PrompterBuilder, supports LiteLLM for model routing, and includes guidelines for contributing chemistry questions using LaTeX and specific JSON schemas.

Tokens
11.3K
Snippets
29
Records
46
Agent score
50%

What's inside ChemBench

  1. Overview of ChemBench

    dev

    ChemBench is a modular Python package designed for building and running benchmarks for Large Language Models (LLMs) and multimodal models (such as vision-language models). It is specifically optimized for chemistry-related tasks but is extensible for other domains.

    Key capabilities include:

    • Standardized Tasks: Uses a format based on Google's Big Bench.
    • Unified Model Interface: Supports LLMs and VLLMs, often utilizing LiteLLM as a backend.
    • Advanced Evaluation: Supports floating-point answers (including scientific notation) and various extraction techniques (e.g., LLM-based extraction).
    • Extensibility: A pipeline system allows customization of prompts, models, extraction, and evaluation methods.
    • Performance Features: Includes result caching, parallelized inference, and refusal detection to handle models that decline to answer.
  2. Overview of ChemBench capabilities

    dev

    ChemBench is a benchmarking suite designed to evaluate Large Language Models (LLMs) on chemistry tasks. It contains over 2,700 question-answer pairs covering knowledge, intuition, and reasoning.

    Key features include:

    • Diverse Question Types: Supports more than simple Multiple Choice Questions (MCQs), including floating-point answers and scientific notation.
    • Specialized Prompting: Provides separate prompting strategies for Completion models, Instruction-tuned models, and special string decorations like SMILES.
    • Advanced Evaluation: Includes refusal detection (identifying when a model refuses to answer), confidence prompting (asking models to estimate their own certainty), and scientifically sound parsing for numerical values.
    • Extensibility: Uses a pipeline system that allows users to add or customize prompts, models, extraction methods, and evaluation methods.
    • Unified Model Interface: Supports LLMs, VLLMs, and other models, often utilizing LiteLLM as a backend.
  3. Keyword and Tagging guidelines

    dev

    Every question must include specific keywords to facilitate filtering and evaluation. All keywords must be lowercase and use - as a separator.

    Required Keyword Pools

    • Requirement Pool (Must include at least one):
      • requires-knowledge: Relies on pre-existing scientific facts/formulas.
      • requires-reasoning: Requires logical inference or data interpretation.
      • requires-calculation: Requires mathematical/quantitative processing.
      • requires-tooluse: Requires external tools (calculators, code environments).
      • requires-ocr: (Multimodal only) Requires extracting text from images.
    • Difficulty Pool (Must include at least one):
      • difficulty-basic: Undergraduate level concepts.
      • difficulty-advanced: Graduate level or multi-subject concepts.

    Optional Keywords

    • Domain/Specialization: e.g., material-science, solid-state-battery.
    • Task Type: multiple-correct-answer, requires-multiple-steps.
  4. How ChemBench parses model responses

    dev

    ChemBench uses a multi-step parsing workflow to extract answers from model completions to ensure robust and fair evaluation. The strategy differs based on the model type:

    1. Prompting Strategy

    • Instruction-tuned models: Prompted to use a specific [ANSWER][\ANSWER] environment to report the final answer.
    • Completion models: Standard completion prompting is used.
    • Consistency: The workflow post-processes LaTeX syntax, chemical symbols, equations, and physical units to ensure consistent parsing.

    2. Parsing Workflow

    • Regex-based Extraction: The primary method uses regular expressions to identify the answer environment and extract enumeration letters (for MCQs) or numbers (for numeric tasks).
    • Scientific Notation: Regex is specifically engineered to handle various forms of scientific notation and convert word-based numbers to floats.
    • LLM Fallback: If hard-coded regex parsing fails, the system uses the same LLM being tested as a fallback to parse its own completion.

    3. Refusal Detection

    To handle cases where a model refuses to answer, ChemBench employs a pipeline combining:

    • LLM Guard: Regular expression-based detection.
    • BERT Model: A fine-tuned distilroberta-base-rejection-v1 model.
    • Retries: If a refusal is detected, the system can perform up to n retry attempts (where n is user-defined).
  5. Understand the ChemBench evaluation metrics

    dev

    ChemBench evaluates model capabilities in chemistry using a primary metric called Fraction Correct. This metric is an aggregation of scores from two types of questions: Multiple-Choice Questions (MCQ) and Numeric questions.

    Scoring Rules

    • Binary Scoring: For any single question, the score is either 0 or 1 (represented as all_correct in the benchmark).
    • MCQ (Multiple-Choice): A question is correct if the Hamming Loss is 0. For single-answer MCQs, this means the predicted label matches the true label.
    • Numeric: A question is correct if the Mean Absolute Error (MAE) is within a 1% threshold of the target value: $$ ext{MAE}_j < 0.01 imes | ext{Target}_j|$$

    Final Score Calculation

    The final score is the mean of the scores of all questions across all topics: $$ ext{Fraction Correct} = rac{1}{n} imes ext{Total Correct Questions}$$

    Key Limitations

    • No Partial Credit: There is no partial scoring for open-ended or complex answers; a question is strictly correct or incorrect.
    • Equal Weighting: All questions are treated with equal weight regardless of difficulty level.
    • Threshold Sensitivity: Numeric accuracy is highly dependent on the 1% MAE threshold.
    \text{Fraction Correct} = \frac{1}{n} \left( \sum_{i \in \text{MCQ}} (1 - \text{HammingLoss}_i) + \sum_{j \in \text{Numeric}} \mathbb{1}(\text{MAE}_j < 0.01 \times |\text{Target}_j|) \right)
  6. ChemBench evaluation design and scope

    dev

    ChemBench is designed as an automated, scalable benchmark for comparative metrics in LLM training.

    Core Design Principles:

    • End-to-end automation: Designed for frequent runs during model development without human scoring.
    • Black-box compatibility: Operates on text completions, making it usable with proprietary systems or models that require external tools (search APIs, code executors).
    • Scientific Rigor: Uses expert-curated questions to minimize noise and ensures support for special tokenization/encoding used by models for molecules or equations.
    • Topic Coverage: Includes dedicated questions for Safety and measures of alignment with human intuition.

    Limitations:

    • Does not currently support the evaluation of open-ended chemistry tasks.
  7. Customize Post-Processing for Scientific Notations

    dev

    ChemBench tasks use specific LaTeX formats and annotations for scientific data. You can control how these are handled during prompting using post_process_<syntax> hooks. Common hooks include:

    • post_process_ce: Handles chemical entity (ce) tags.
    • post_process_math: Handles math ($) tags. Use remove_math to strip $ wrapping or passthrough if the model expects it.
    • post_process_pu: Handles physical unit (pu) tags.
    • post_process_smiles: Handles [BEGIN_SMILES][END_SMILES] tags.
    • post_process_rxnsmiles: Handles [BEGIN_RXNSMILES][END_RXNSMILES] tags.
    • other: Handles other entities (like chemical elements) via a custom function.
  8. Use ChemBench Caching to Resume Evaluations

    dev

    ChemBench saves results to a local pickle file named state.pkl to avoid re-running the same prompts. If an evaluation is interrupted, simply run the script again; the cache will be loaded and the evaluation will continue from the last task.

    Caution: If state.pkl is removed, the evaluation will restart from the beginning.

  9. How ChemBench handles LLM refusals

    dev

    To prevent model refusals from skewing results, ChemBench implements a detection and retry mechanism:

    1. Detection: A combination of regular expression-based detection (via LLM Guard) and a fine-tuned BERT model (distilroberta-base-rejection-v1) is used to identify potential refusals.
    2. Mitigation: If a refusal is detected, an interval-based retry mechanism is triggered, re-querying the LLM up to $n$ times until a non-refusal response is obtained.
    3. Scoring: Refusals are ultimately counted as incorrect in the final score.
  10. How to contribute new questions to ChemBench

    dev

    You can contribute new questions to ChemBench using one of three methods:

    1. GitHub Pull Request: Fork the repository, create a branch, add your question as a single JSON file in the data directory, and submit a PR to the develop branch. The CI will automatically validate your JSON formatting.
    2. Google Form: If you prefer not to use Git, fill out the Google Form. Note that the form accepts only one question per submission.
    3. Email: Send your questions to chembench@lamalab.org for maintainer review and addition.
  11. Benchmark a local vision model (Non-API Models)

    dev

    Benchmarking vision models follows the same pattern as text models but requires handling multi-modal inputs.

    Implementation Details:

    • Message Transformation: Since ChemBench uses a standard message format (similar to LiteLLM), you may need a helper method (e.g., _transform_message) to convert these messages into the specific format your model's processor expects (e.g., handling image_url or base64 data).
    • Prompt Formatting: You must implement logic to process both text and image/video inputs using your model's specific processor (e.g., AutoProcessor from HuggingFace).
    • Standard Message Format: ChemBench provides messages in a format where content can be a list of objects containing type: "text" or type: "image_url" (with base64 encoded data).

    Workflow:

    1. Implement a class with a .generate(prompts: List[str], **kwargs) method.
    2. Use PromterBuilder.from_model_object(model=your_vision_model).
    3. Run benchmark.bench(prompter).

    Note: For multi-modal benchmark datasets, use jablonkagroup/MaCBench when initializing the benchmark.

    from chembench.types import Generation, Generations
    from chembench.evaluate import ChemBenchmark
    from chembench.prompter import PrompterBuilder
    
    class QwenVL:
        # ... implementation of _transform_message, format_prompt, and generate_text ...
    
        def generate(self, prompts: List[str], **kwargs):
            generations = []
            for prompt in prompts:
                generation = self.generate_text(prompt, **kwargs)
                generations.append([Generation(text=generation)])
            return Generations(generations=generations)
    
    benchmark = ChemBenchmark.from_huggingface()
    model = QwenVL()
    prompter = PrompterBuilder.from_model_object(model=model)
    results = benchmark.bench(prompter)
  12. Benchmark only on selected topics

    dev

    You can limit your evaluation to specific chemistry or materials science topics. First, use benchmark.echo_topics() to see the list of available topics. Then, pass the desired topics as a list to the topics argument in benchmark.bench().

    from chembench.evaluate import ChemBenchmark
    from chembench.prompter import PrompterBuilder
    from chembench.utils import enable_logging
    
    enable_logging()
    benchmark = ChemBenchmark.from_huggingface()
    
    # List available topics
    benchmark.echo_topics()
    
    # Benchmark specific topics
    prompter = PrompterBuilder.from_model_object('openai/gpt-4')
    results_topic_wise = benchmark.bench(prompter, topics=['analytical_chemistry', 'general_chemistry'])