Synthetic Data Kit

repository·main·Indexed 23 days ago

https://github.com/meta-llama/synthetic-data-kit

A tool for generating high-quality synthetic datasets, such as Reasoning Traces and QA Pairs, to fine-tune LLMs. It features a modular 4-stage pipeline (ingest, create, curate, and save-as) to transform raw data from PDF, HTML, DOCX, PPTX, TXT, and YouTube URLs into fine-tuning formats like alpaca, chatml, and ft. The kit supports vLLM and API backends, multimodal QA generation, and a cot-enhance command for adding reasoning to tool-use conversations.

Tokens
26.5K
Snippets
66
Records
102
Agent score
81%

What's inside synthetic-data-kit

  1. Overview of Synthetic Data Kit

    main

    Synthetic Data Kit is a modular toolkit designed to prepare high-quality synthetic datasets for fine-tuning Large Language Models (LLMs). It provides a command-line interface (CLI) to manage a 4-stage data preparation workflow:

    1. Document Parsing: Converts various file formats (PDF, HTML, YouTube, DOCX, PPTX, TXT) into clean text.
    2. Content Generation: Uses local LLM inference to generate high-quality QA pairs.
    3. Quality Control: Filters generated content based on specific quality metrics.
    4. Format Conversion: Exports the final data into training formats like JSONL, Alpaca, OpenAI FT, and ChatML.

    The entire workflow is configurable via YAML and is designed to be extensible for new parsers, generators, or output formats.

  2. Stage 1: Document Parsing (Ingest)

    main

    The ingest stage converts various document formats into plain text. The toolkit automatically selects the appropriate parser based on the file extension or URL pattern.

    Supported Formats:

    • Files: .pdf, .html, .htm, .docx, .pptx, .txt
    • URLs: YouTube links (youtube.com or youtu.be) are parsed using the YouTubeParser, while other URLs use the HTMLParser.
  3. Optimize performance based on document size

    main

    Adjust your --chunk-size based on the character count of your documents to balance quality and performance:

    Document SizeRecommended Strategy
    Small (< 8,000 chars)Let the tool use single-call processing automatically.
    Medium (8,000 - 50,000 chars)Use default settings (--chunk-size 4000).
    Large (> 50,000 chars)Use larger chunks (--chunk-size 6000-8000).
    Very LargeProcess in smaller batches with fewer --num-pairs per run.
  4. How the Synthetic Data Kit 4-stage pipeline works

    main

    The toolkit follows a modular 4-command CLI workflow to transform raw files into fine-tuning datasets. The default storage format for intermediate steps is Lance.

    1. ingest: Parses various file formats (PDF, HTML, DOCX, PPTX, TXT, YouTube URLs) into a structured format.
    2. create: Uses an LLM backend to generate synthetic content such as QA pairs, QA pairs with Chain of Thought (cot), or summary formats.
    3. curate: Uses Llama as a judge to filter and select high-quality examples based on a quality threshold.
    4. save-as: Converts the curated data into specific fine-tuning formats (e.g., alpaca, chatml, ft) and storage types (e.g., hf for Hugging Face arrow files).

    You can process either individual files or entire directories using these commands.

  5. Stage 4: Format Conversion (Save-as)

    main

    The save-as stage converts processed content from the internal JSON format into various training-ready formats.

    Supported Output Formats:

    • jsonl: JSON Lines format.
    • alpaca: Alpaca instruction format.
    • ft: Fine-tuning format.
    • chatml: ChatML format.

    Storage Options: Converted data can be saved as standard JSON files or as a Hugging Face (HF) Dataset (which uses the Arrow format).

  6. Stage 3: Content Filtering (Cleanup)

    main

    The cleanup stage filters generated content based on quality ratings. It uses an LLM to rate content and then applies a threshold to keep only high-quality items.

    Key Features:

    • Batch Processing: Processes QA pairs in batches for efficiency.
    • Fallback Mechanism: If batch processing fails (e.g., due to parsing errors), the system automatically falls back to processing items individually.
    • Robust JSON Parsing: Uses multiple methods (Pretty-Printed JSON, Code Block Extraction, Regex, JSON5, and Pattern Matching) to handle varied LLM output formats.
    • Configuration: Batch sizes can be controlled via the configuration file or overridden using the SDK_BATCH_SIZE environment variable for debugging.
  7. Stage 2: Content Generation (Create)

    main

    The create stage generates synthetic content (such as summaries or QA pairs) from parsed text. For long documents, the toolkit performs text chunking to ensure content is manageable for LLM inference.

    Text Chunking Logic: Text is split into chunks based on a chunk_size (default 4000) and an overlap (default 200). The system attempts to maintain context by preserving the last few sentences of a chunk when starting a new one.

  8. Configure document chunking and overlap

    main

    Large documents (≥ 8000 characters) are automatically split into overlapping chunks. You can control this behavior using --chunk-size and --chunk-overlap.

    ParameterDefaultBest ForDescription
    --chunk-size4000Detailed analysisSmaller values (e.g. 2000) provide more detail but are slower
    --chunk-overlap200Reducing repetitionMinimal overlap between chunks
    --chunk-overlap200Preserving contextLarger values (e.g. 400) preserve more context

    Example usage:

    synthetic-data-kit create data/output/large_document.txt --chunk-size 2000 --chunk-overlap 100
  9. Understand the Synthetic Data Kit 4-stage pipeline mental model

    main

    The Synthetic Data Kit operates through a structured pipeline consisting of four main stages:

    1. Ingest: Consumes raw data from various sources like PDF files, HTML files, or YouTube URLs.
    2. Create: Generates synthetic content such as Chain-of-Thought (CoT) reasoning, QA pairs, or Summaries.
    3. Curate: Refines the generated data by filtering for quality.
    4. Save-as: Exports the final dataset into formats like JSONL, Alpaca, Fine-Tuning (FT), or ChatML.
  10. How the Synthetic Data Kit architecture works

    main

    The toolkit follows a modular architecture where a central Core manages the flow between specialized components. The main components include:

    • Parsers: Specialized modules (e.g., PDFParser, YouTubeParser) that handle document ingestion.
    • Generators: Modules like QAGenerator that handle content creation logic.
    • LLMClient: Manages communication with inference servers (like VLLM) and handles batch processing.
    • FormatConverter: Handles the final export to training-ready formats.
    • CLI Interface: The entry point that orchestrates these components using a configuration system.

    Data flows through a pipeline: Files are ingested and parsed into text $\rightarrow$ text is processed by generators to create QA pairs $\rightarrow$ QA pairs are curated/filtered $\rightarrow$ cleaned data is converted to a final training format.

  11. Enhance API usage examples with documentation (cot-enhance)

    main

    To improve model performance in tool calling (inspired by the Gorilla paper), you can use the cot-enhance type to add detailed API documentation and reasoning to existing conversation examples.

    Workflow

    1. Prepare base data: Create a JSON file containing basic API usage examples (e.g., simple Q&A pairs without detailed documentation).
    2. Enhance: Run the create command with the --type cot-enhance flag. This uses a custom cot_enhancement prompt to inject relevant API syntax, parameter descriptions, and step-by-step reasoning into the assistant's responses.
    3. Save: Use the save-as command to export the enhanced dataset in a format like chatml.

    Example Configuration

    llm:
      provider: "vllm"
    
    vllm:
      api_base: "http://localhost:8000/v1"
      model: "meta-llama/Llama-3.3-70B-Instruct"
    
    generation:
      temperature: 0.3
      num_pairs: 15
    
    curate:
      threshold: 8.0
      batch_size: 10
    
    prompts:
      # Custom rating prompt for API documentation quality
      qa_rating: |\n    Rate these API usage examples on a scale from 1-10 based on:\n    \n    - Documentation quality (0-3): Is the API documentation clear and complete?\n    - API call correctness (0-3): Is the syntax and usage correct?\n    - Explanation quality (0-2): Is the explanation helpful and accurate?\n    - Parameter coverage (0-2): Are parameters well explained and correctly used?\n    \n    Immediately reject any example where the API call doesn't match the documentation.\n    \n    Return valid JSON with ratings:\n    [\n      {"question": "Original question", "answer": "Original answer with documentation", "rating": 8}\n    ]\n    \n    Examples to rate:\n    {pairs}\n    \n  # Custom prompt for enhancing examples with documentation
      cot_enhancement: |\n    You are enhancing API usage examples by adding detailed documentation.\n    \n    For each conversation, add the following to the assistant's responses:\n    1. Relevant API documentation with syntax and parameter descriptions\n    2. Clear explanation of why this API is appropriate\n    3. Description of what each parameter does\n    \n    Return the enhanced conversations as a JSON array matching this format:\n    [\n      {\n        "role": "system", \n        "content": "System message"\n      },\n      {\n        "role": "user", \n        "content": "How do I use function X?"\n      },\n      {\n        "role": "assistant", \n        "content": "Here's the documentation for this API:\n\n```\nfunction X(param1, param2) -> return_type\n  param1: description of param1\n  param2: description of param2\n  returns: what is returned\n```\n\nHere's how you can use it:\n\n```python\nresult = X(value1, value2)\n```\n\nThis works because [detailed explanation]..."\n      }\n    ]\n    \n    Original conversations:\n    {conversations}\nEOF
    # Enhance existing examples with documentation using cot-enhance
    # 1. First prepare a JSON file with basic API usage examples (without detailed docs)
    # Example: api_examples.json with basic Q&A pairs about APIs
    
    # 2. Enhance these examples by adding detailed documentation
    synthetic-data-kit -c gorilla_config.yaml create data/api_examples.json --type cot-enhance
    
    # 3. Save the enhanced dataset
    synthetic-data-kit -c gorilla_config.yaml save-as data/generated/api_examples_enhanced.json -f chatml
  12. Add a new generator type

    main

    To implement a new generation logic (e.g., Chain-of-Thought):

    1. Create the generator class: In the generators/ directory, create a class that accepts an LLMClient and an optional config_path. Implement your generation logic (e.g., generate_cot_examples).
    2. Define the prompt: Add the corresponding prompt template to config.yaml under the prompts: key.
    3. Integrate with the CLI/Core: Update the process_file logic (or the relevant command handler) to instantiate your new generator and handle the output saving when the specific content_type is requested.
    # synthetic_data_kit/generators/cot_generator.py
    from typing import Dict, List, Any, Optional
    import json
    from synthetic_data_kit.models.llm_client import LLMClient
    from synthetic_data_kit.utils.config import get_prompt
    
    class COTGenerator:
        """Generates chain-of-thought reasoning examples"""
        
        def __init__(self, client: LLMClient, config_path: Optional[str] = None):
            self.client = client
            self.config = client.config
        
        def generate_cot_examples(self, document_text: str, num_examples: int = 5) -> List[Dict[str, Any]]:
            prompt_template = get_prompt(self.config, "cot_generation")
            prompt = prompt_template.format(num_examples=num_examples, text=document_text)
            
            messages = [{"role": "system", "content": prompt}]
            response = self.client.chat_completion(messages)
            
            examples = []
            if '[' in response and ']' in response:
                start = response.find('[')
                end = response.rfind(']') + 1
                try:
                    examples = json.loads(response[start:end])
                except:
                    print("Error parsing COT examples")
            
            return examples