MCPcopy Index your code
hub / github.com/bespokelabsai/curator

github.com/bespokelabsai/curator @v0.1.28

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.1.28 ↗ · + Follow
1,451 symbols 5,127 edges 172 files 1,015 documented · 70%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

  <img alt="Bespoke Labs Logo" width="100px" src="https://github.com/bespokelabsai/curator/blob/main/docs/Bespoke-Labs-Logomark-Red-crop.png">

Bespoke Curator

Bulk Inference and Scalable Data Curation for Post-Training

Github Twitter Hugging Face Discord

Docs Website PyPI

[ English | 中文 ]

🎉 What's New

Overview

Bespoke Curator makes it easy to create synthetic data pipelines. Whether you are training a model or extracting structured data, Curator will prepare high-quality data quickly and robustly.

  • Rich Python based library for generating and curating synthetic data.
  • Viewer to monitor data while it is being generated.
  • First class support for structured outputs.
  • Built-in performance optimizations for asynchronous operations, caching, and fault recovery at every scale.
  • Support for a wide range of inference options via LiteLLM, vLLM, and popular batch APIs.

CLI in action

Check out our full documentation for getting started, tutorials, guides and detailed reference.

🛠️ Installation

pip install bespokelabs-curator

📕 Examples

Finetuning/Distillation

Task Link(s) Goal
Product feature extraction Open In Colab Finetuning a model to identify features of a product
Sentiment analysis Open In Colab Aspect-based sentiment analysis of restaurant reviews and finetuning using Together.ai
RAFT for domain-specific RAG Code Implement Retrieval Augmented Fine-Tuning (RAFT) that processes domain-specific documents, generates questions, and prepares data for fine-tuning LLMs.
Poem generation & LoRA fine-tuning Code End-to-end pipeline: curate poem data with Curator, then LoRA fine-tune with TinkerTrainer
Managed fine-tuning on Fireworks AI Code Run a managed SFT job on Fireworks AI with FireworksTrainer, then sample from the deployed LoRA model

Data Generation

Task Link(s) Goal
Reasoning dataset generation (Bespoke Stratos) Code Generate the Bespoke-Stratos-17k dataset, focusing on reasoning traces from math, coding, and problem-solving datasets.
Reasoning dataset generation (Open Thoughts) Code Generate the Open-Thoughts-114k dataset, focusing on reasoning traces from math, coding, and problem-solving datasets.
Multimodal Code Demonstrates multimodal capabilities by generating recipes from food images
Ungrounded Question Answer generation Code Generate diverse question-answer pairs using techniques similar to the CAMEL paper
Code Execution Open In Colab Execute code generated with Curator
3Blue1Brown video generation Code Generate videos similar to 3Blue1Brown and render them using code execution!
Synthetic charts Code Generate charts synthetically.
Function calling Code Generate data for finetuning for function calling.

🚀 Quickstart

Using curator.LLM for Bulk Inference

from typing import Dict
from bespokelabs import curator
from datasets import Dataset
from pydantic import BaseModel, Field
from typing import Literal

class Sentiment(BaseModel):
  sentiment: Literal["positive", "negative", "neutral"] = Field(
    description="Sentiment of the review")

class SentimentAnalyzer(curator.LLM):

  def prompt(self, product: Dict):
    return f"Determine the sentiment of the product from the review: {product['review']}"

  def parse(self, product: Dict, response: Sentiment):
    return [{"name": product["name"], "sentiment": response.sentiment}]

# You can easily have a million rows here. 
# Curator takes care of parallelism, retries, and caches responses.
dataset = [{"name": "Curator", "review": "Already saved hours in one day of use."},
           {"name": "Bespoke MiniCheck", "review": "Hallucination rates dropped by 90%."}]

# You can set batch=True, and instantly uses batch mode to save 50% of the costs.
analyzer = SentimentAnalyzer(
    model_name="gpt-4o-mini", response_format=Sentiment, batch=False)
reviews = analyzer(dataset)
print(reviews.to_pandas())

Output:

                name sentiment
0            Curator  positive
1  Bespoke MiniCheck  positive

In the SentimentAnalyzer class: * prompt takes the input (product) and returns the prompt for the LLM. * parse takes the input (product) and the structured output (response) and converts it to a list of dictionaries. This is so that we can easily convert the output to a HuggingFace Dataset object.

Instead of a list, you can pass a HuggingFace Dataset object as well (see below for more details).

Using curator.LLM for data generation

Here's an example of using structured outputs and chaing together two curator.LLM blocks to generate diverse poems.

from typing import Dict, List
from bespokelabs import curator
from pydantic import BaseModel, Field

class Topics(BaseModel):
    topics_list: List[str] = Field(description="A list of topics.")

class TopicGenerator(curator.LLM):
  response_format = Topics

  def prompt(self, subject):
    return f"Return 3 topics related to {subject}"

  def parse(self, input: str, response: Topics):
    return [{"topic": t} for t in response.topics_list]


class Poem(BaseModel):
    title: str = Field(description="The title of the poem.")
    poem: str = Field(description="The content of the poem.")

class Poet(curator.LLM):
    response_format = Poem

    def prompt(self, input: Dict) -> str:
        return f"Write two poems about {input['topic']}."

    def parse(self, input: Dict, response: Poem) -> Dict:
        return [{"title": response.title, "poem": response.poem}]

topic_generator = TopicGenerator(model_name="gpt-4o-mini")
poet = Poet(model_name="gpt-4o-mini")
# Start generation
topics = topic_generator("Mathematics")
poems = poet(topics)

Output:

    title                     poem
0   The Language of Algebra   In symbols and signs, truths intertwine,..
1   The Geometry of Space     In the world around us, shapes do collide,..
2   The Language of Logic     In circuits and wires where silence speaks,..

You can see more examples in the examples directory.

See the docs for more details as well as for troubleshooting information.

[!TIP] If you are generating large datasets, you may want to use batch mode to save costs. Currently batch APIs from OpenAI and Anthropic are supported. With curator this is as simple as setting batch=True in the LLM class. [!NOTE] Retries and caching are enabled by default to help you rapidly iterate your data pipelines. So now if you run the same prompt again, you will get the same response, pretty much instantly. You can delete the cache at ~/.cache/curator or disable it with export CURATOR_DISABLE_CACHE=true.

[!IMPORTANT] Make sure to set your API keys as environment variables for the model you are calling. For example running export OPENAI_API_KEY=sk-... and export ANTHROPIC_API_KEY=ant-... will allow you to run the previous two examples. A full list of supported models and their associated environment variable names can be found in the litellm docs.

Anonymized Telemetry

We collect minimal, anonymized usage telemetry to help prioritize new features and improvements that benefit the Curator community. You can opt out by setting the TELEMETRY_ENABLED environment variable to False.

📖 Providers

Curator supports a wide range of providers, including OpenAI, Anthro

Core symbols most depended-on inside this repo

append
called by 119
src/bespokelabs/curator/types/curator_response.py
update
called by 30
src/bespokelabs/curator/finetune/status_tracker.py
load_dataset
called by 26
src/bespokelabs/curator/utils.py
push_to_hub
called by 18
src/bespokelabs/curator/request_processor/base_request_processor.py
add
called by 18
src/bespokelabs/curator/types/curator_response.py
from_dict_messages
called by 15
src/bespokelabs/curator/finetune/types.py
run_in_event_loop
called by 14
src/bespokelabs/curator/request_processor/event_loop.py
train
called by 14
src/bespokelabs/curator/finetune/trainer/base_trainer.py

Shape

Method 812
Function 373
Class 262
Route 4

Languages

Python100%

Modules by API surface

tests/finetune/test_fireworks_trainer.py58 symbols
tests/finetune/test_trainer.py42 symbols
examples/bespoke-stratos-data-generation/util/testing/pyext2.py42 symbols
tests/integrations/test_all.py38 symbols
src/bespokelabs/curator/status_tracker/batch_status_tracker.py36 symbols
tests/integrations/helper.py34 symbols
src/bespokelabs/curator/request_processor/batch/base_batch_request_processor.py33 symbols
src/bespokelabs/curator/finetune/trainer/fireworks_trainer.py31 symbols
src/bespokelabs/curator/request_processor/online/base_online_request_processor.py28 symbols
src/bespokelabs/curator/status_tracker/online_status_tracker.py26 symbols
src/bespokelabs/curator/request_processor/online/litellm_online_request_processor.py26 symbols
tests/code_executor/test_backend.py24 symbols

For agents

$ claude mcp add curator \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page