Skip to main content

LLM-powered synthetic text data generation for text classification tasks, with multi-strategy generation, multilingual support, and quality filtering.

Project description

synthetictext

LLM-powered synthetic text data generation for text classification, style transfer, and RAG evaluation tasks.

synthetictext generates high-quality synthetic training data for any text classification task across multiple languages. It provides five generation strategies, a multi-stage quality filtering pipeline, and a simple Python API.

Features

  • Task-agnostic: Define any binary or multi-class text classification task via a TaskSpec
  • 5 generation strategies: Direct generation, paraphrasing, contrastive pairs, backtranslation, and pivot translation
  • Multi-stage quality filtering: Deduplication, label leakage detection, embedding-based dedup, LLM-as-judge, and keyword marker checks
  • Multilingual: Generate data in any language supported by your LLM provider, with optional cross-lingual transfer for low-resource languages
  • Provider-agnostic: Built-in support for OpenAI; extensible via BaseLLMProvider and BaseTranslationProvider interfaces
  • RAG Q&A generation: Create grounded question-answer pairs from a source chunk for RAG evaluation
  • Templated generation: Transfer a source text's style to a caller-provided target topic, especially useful for pretraining data and style transfer tasks.
  • CLI and Python API: Use from scripts or the command line

Installation

# Core (no LLM provider included)
pip install synthetictext

# With OpenAI support (most common)
pip install synthetictext[openai]

# With embedding-based deduplication
pip install synthetictext[embeddings]

# With Google Cloud Translation (for backtranslation/pivot strategies)
pip install synthetictext[google-translate]

# With YAML config file support for the CLI
pip install synthetictext[yaml]

# Everything
pip install synthetictext[all]

Authentication

The library needs an API key for the LLM provider. There are three ways to provide it:

Option 1: Environment variable (recommended)

export OPENAI_API_KEY="sk-..."

Then just use the shorthand -- the OpenAI SDK picks up the env var automatically:

generator = SyntheticDataGenerator(task=task, llm_provider="openai")

Option 2: Explicit API key

generator = SyntheticDataGenerator(
    task=task,
    llm_provider="openai",
    llm_model="gpt-4o-mini",
    api_key="sk-...",
)

Option 3: Direct provider construction (full control)

from synthetictext.providers.openai_provider import OpenAIProvider

provider = OpenAIProvider(api_key="sk-...", default_model="gpt-4o")
generator = SyntheticDataGenerator(task=task, llm_provider=provider)

The model defaults to gpt-4o-mini but can be overridden via llm_model or --model on the CLI.

Quick Start

from synthetictext import TaskSpec, SyntheticDataGenerator

# 1. Define your classification task
task = TaskSpec(
    name="Sentiment Analysis",
    labels={0: "negative", 1: "positive"},
    description="Classify product reviews as positive or negative sentiment.",
    label_descriptions={
        0: "A review expressing dissatisfaction, criticism, or negative experience.",
        1: "A review expressing satisfaction, praise, or positive experience.",
    },
    topics={
        "electronics": ["smartphones", "laptops", "headphones"],
        "food": ["restaurants", "delivery", "recipes"],
    },
)

# 2. Create a generator
generator = SyntheticDataGenerator(
    task=task,
    llm_provider="openai",  # uses OPENAI_API_KEY env var
    llm_model="gpt-4o-mini",
)

# 3. Generate data
df = generator.generate(
    language="English",
    num_samples=1000,
    strategies=["direct", "paraphrase", "contrastive"],
    strategy_weights=[0.5, 0.3, 0.2],
)

print(df.head())
# Columns: id, text, label, source, generated_at, language

RAG Q&A Generation

Generate grounded question-answer pairs from a source text chunk for future RAG evaluation datasets:

from synthetictext import RAGQAGenerator

chunk = """
Synthetictext can generate classification data and RAG Q&A examples.
The RAG Q&A feature creates questions answerable only from the source chunk.
"""

qa_generator = RAGQAGenerator(llm_provider="openai", llm_model="gpt-4o-mini")
qa_df = qa_generator.generate(chunk=chunk, num_samples=3, language="English")

print(qa_df.head())
# Columns: id, question, answer, source, metadata

From the CLI:

synthetictext rag-qa --input chunk.txt --num-samples 5 --language English --output qa.csv

Templated Generation

Generate new text on a different topic while preserving the source text's style, tone, structure, and approximate length:

from synthetictext import TemplatedGenerator

source_text = "EV adoption is accelerating as battery costs fall and charging networks expand."

templated = TemplatedGenerator(llm_provider="openai", llm_model="gpt-4o-mini")

text = templated.generate_one(
    text=source_text,
    source_topic="electric vehicles",
    target_topic="urban gardening",
    style="brief analytical market update",
    language="English",
)

df = templated.generate(
    text=source_text,
    source_topic="electric vehicles",
    target_topic="urban gardening",
    style="brief analytical market update",
    num_samples=5,
    language="English",
)

print(text)
print(df.head())
# Columns: id, text, source, metadata

From the CLI:

synthetictext templated \
    --input source.txt \
    --source-topic "electric vehicles" \
    --target-topic "urban gardening" \
    --style "brief analytical market update" \
    --num-samples 5 \
    --output templated.csv

Generation Strategies

Strategy Description Requires
direct Generate new samples in the target language LLM
paraphrase Rewrite existing samples preserving labels LLM + training data
contrastive Generate minimal pairs (one per class, same topic) LLM
backtranslation Round-trip translate through a pivot language Translation API + training data
pivot Generate in English, translate to target language LLM + Translation API

Quality Filtering

The default filtering pipeline runs these steps in order:

  1. BasicFilter -- remove empty, null, or out-of-range-length samples
  2. LeakageFilter -- remove samples containing label leakage patterns (e.g., "this is a positive example")
  3. EmbeddingDeduplicator -- remove near-duplicates using multilingual sentence embeddings (cosine similarity > 0.90)
  4. MarkerFilter -- (optional) ensure samples for specific labels contain expected keywords

Additional optional filters:

  • LLMJudgeFilter -- use an LLM to validate realism, label correctness, clarity, and grammar
  • TranslationQualityFilter -- check round-trip translation consistency for pivot/backtranslation samples

Multilingual Generation

from synthetictext import LanguageConfig

lang_config = LanguageConfig(
    languages={"en": "English", "de": "German", "es": "Spanish"},
    related_languages={"es": "en"},  # cross-lingual transfer
)

generator = SyntheticDataGenerator(
    task=task,
    llm_provider="openai",
    lang_config=lang_config,
)

# Generate for all configured languages
results = generator.generate_all(num_samples=500)

CLI Usage

# Generate from a JSON task config
synthetictext generate --config task.json --language en --num-samples 1000

# Generate for all languages
synthetictext generate --config task.json --all --num-samples 500 --output-dir ./output

# Multiple strategies with weights
synthetictext generate --config task.json -l en -n 1000 \
    --strategies direct paraphrase contrastive \
    --weights 0.5 0.3 0.2

# Filter existing synthetic data
synthetictext filter --config task.json --input synthetic.csv --output filtered.csv

# Generate templated style-transfer text
synthetictext templated --input source.txt \
    --source-topic "electric vehicles" \
    --target-topic "urban gardening" \
    --style "brief analytical market update" \
    --num-samples 5 --output templated.csv

Task Config File (JSON)

{
    "name": "Toxicity Detection",
    "labels": {"0": "non-toxic", "1": "toxic"},
    "description": "Classify social media posts as toxic or non-toxic.",
    "label_descriptions": {
        "0": "A post that discusses topics respectfully.",
        "1": "A post containing insults, threats, or dehumanizing language."
    },
    "text_domain": "social media post",
    "word_count_range": [20, 80],
    "topics": {
        "political": ["elections", "government policy"],
        "social": ["gender issues", "immigration"]
    }
}

Custom Providers

Extend BaseLLMProvider to use any LLM backend:

from synthetictext.providers.base import BaseLLMProvider

class AnthropicProvider(BaseLLMProvider):
    def generate(self, prompt, *, model=None, temperature=0.9,
                 max_tokens=250, system_prompt=None):
        # Your Anthropic API call here
        ...

Tutorials

Step-by-step Jupyter notebooks in tutorials/:

  1. Quick Start -- defining tasks, generating data, combining strategies
  2. Quality Filtering -- using built-in filters, building custom filter pipelines
  3. Multilingual Generation -- LanguageConfig, backtranslation, pivot translation, tier-based strategies
  4. RAG Q&A Generation -- generating grounded question-answer pairs from source chunks
  5. Templated Generation -- transferring a source text's style to a new topic

Examples

Development

git clone https://github.com/srikarkashyap/synthetictext.git
cd synthetictext
pip install -e ".[dev]"
pytest

Origin

This library was developed from the synthetic data pipeline used in the PSK system for SemEval-2026 Task 9: Multilingual Polarization Detection, where it generated training data across 22 languages and contributed to a 2nd-place finish.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

synthetictext-0.2.0.tar.gz (58.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

synthetictext-0.2.0-py3-none-any.whl (46.4 kB view details)

Uploaded Python 3

File details

Details for the file synthetictext-0.2.0.tar.gz.

File metadata

  • Download URL: synthetictext-0.2.0.tar.gz
  • Upload date:
  • Size: 58.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.13

File hashes

Hashes for synthetictext-0.2.0.tar.gz
Algorithm Hash digest
SHA256 fe0a1a05a4d78a1e3aa5aeeb8ada9f0f6e96ed3f37581cc515b2e58174e0572a
MD5 158336bd5e9129477121bfd14edd2ae2
BLAKE2b-256 b99ded4528549200b1938b32fd83e51c199ef5777074e17e991f6c945e06f3c1

See more details on using hashes here.

File details

Details for the file synthetictext-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: synthetictext-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 46.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.13

File hashes

Hashes for synthetictext-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 042ce8f08ce228800e3201f92b08ab39d761be4daa40f1796f45091d5f0f36f2
MD5 5d8163679bab26590e1ba210a36ca5bf
BLAKE2b-256 ffb554d8c47d20430debb7c843253b3550b2c0ac1f53227b4b5dab5ad3842d4d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page