ML data toolkit - 29 features for dataset processing
Project description
bellapy
A lightweight, production-tested data preparation toolkit for ML practitioners.
Stop rewriting the same data cleaning scripts. Your personal ML operations library, extracted from real production workflows.
The Problem
You've written the same scripts 100 times:
deduplicate_data.py- MD5 hashing, againmerge_datasets.py- Combining JSONLs, againscrub_pii.py- Regex hell, againconvert_format.py- OpenAI vs HF, again
Every project. Every time. Different folder. Different bugs.
The Solution
One library. One command. Forever.
bellapy data dedupe my_dataset.jsonl
That's it. No copying scripts. No finding "that file from 3 months ago."
What is bellapy?
A pip-installable toolkit for ML practitioners who are tired of reinventing the wheel.
Built from real ML workflows - not academic examples. This is the code that:
- Cleaned 15,000+ training examples
- Powered DPO data collection for production models
- Processed datasets for Llama, Qwen, Dolphin, and Gemma fine-tunes
- Merged hundreds of conversation datasets
It's not a framework. It's your personal library.
Quick Start
Install
pip install -e /path/to/bellapy
Use (CLI)
# Remove duplicates
bellapy data dedupe dataset.jsonl
# Merge multiple files
bellapy data merge combined.jsonl file1.jsonl file2.jsonl file3.jsonl
# Scrub PII (emails, phones, API keys, etc.)
bellapy data clean dataset.jsonl
# Convert to OpenAI format
bellapy data convert dataset.jsonl --format openai
# View stats
bellapy data stats dataset.jsonl
Use (Python)
from bellapy.data import deduplicate, merge_files, clean_dataset
deduplicate("raw.jsonl", "unique.jsonl")
clean_dataset("unique.jsonl", "clean.jsonl") # PII scrubbed
๐ฏ Recipes
Recipe 1: Clean & Dedupe Your Dataset
The problem: You have a messy dataset with duplicates and PII.
# Before: 10,000 examples with duplicates and emails/phones
bellapy data dedupe raw_data.jsonl -o step1.jsonl
bellapy data clean step1.jsonl -o clean_data.jsonl
bellapy data stats clean_data.jsonl
# After: 8,500 unique examples, PII replaced with [EMAIL]/[PHONE]
As Python:
from bellapy.data import deduplicate, clean_dataset, get_stats
# Pipeline
deduplicate("raw_data.jsonl", "step1.jsonl")
clean_dataset("step1.jsonl", "clean_data.jsonl", scrub_pii_enabled=True)
# Check results
stats = get_stats("clean_data.jsonl")
print(f"Cleaned {stats['total']} examples, removed {stats['duplicates']} dupes")
Recipe 2: Merge Multiple Sources
The problem: You have 5 datasets from different sources. Need one clean file.
bellapy data merge combined.jsonl \
organic_convos.jsonl \
synthetic_data.jsonl \
user_feedback.jsonl \
reddit_scrape.jsonl \
gpt_generated.jsonl
# Automatically deduplicates during merge
bellapy data stats combined.jsonl
As Python:
from bellapy.data import merge_files
sources = [
"organic_convos.jsonl",
"synthetic_data.jsonl",
"user_feedback.jsonl",
"reddit_scrape.jsonl",
"gpt_generated.jsonl"
]
merge_files("combined.jsonl", sources, dedupe=True)
Recipe 3: Prepare for Fine-Tuning (OpenAI/HF)
The problem: Your dataset is clean but in the wrong format.
# Convert to OpenAI messages format
bellapy data convert dataset.jsonl --format openai -o openai_format.jsonl
# Split train/test (90/10)
bellapy data split openai_format.jsonl --ratio 0.9
# Result: dataset_train.jsonl + dataset_test.jsonl
As Python:
from bellapy.data import convert_format, split_dataset
# Convert
convert_format("dataset.jsonl", "openai_format.jsonl", target_format="openai")
# Split
train_file, test_file = split_dataset("openai_format.jsonl", train_ratio=0.9)
Recipe 4: The Full Pipeline
The problem: You need production-ready data from raw sources.
# 1. Merge all sources
bellapy data merge raw_combined.jsonl source1.jsonl source2.jsonl source3.jsonl
# 2. Deduplicate
bellapy data dedupe raw_combined.jsonl -o unique.jsonl
# 3. Clean (PII + sanitization)
bellapy data clean unique.jsonl -o clean.jsonl
# 4. Convert to training format
bellapy data convert clean.jsonl --format openai -o final.jsonl
# 5. Split train/test
bellapy data split final.jsonl --ratio 0.9
# 6. Check final stats
bellapy data stats final_train.jsonl
One-liner Python version:
from bellapy.data import merge_files, deduplicate, clean_dataset, convert_format, split_dataset
# Full pipeline
sources = ["source1.jsonl", "source2.jsonl", "source3.jsonl"]
merge_files("raw.jsonl", sources)
deduplicate("raw.jsonl", "unique.jsonl")
clean_dataset("unique.jsonl", "clean.jsonl")
convert_format("clean.jsonl", "final.jsonl", target_format="openai")
split_dataset("final.jsonl", train_ratio=0.9)
๐ ๏ธ What's Included
Phase 1: Data Processing โ (Available Now)
| Feature | CLI | Python | What It Does |
|---|---|---|---|
| Deduplication | bellapy data dedupe |
deduplicate() |
MD5 hash-based duplicate removal |
| Merging | bellapy data merge |
merge_files() |
Combine multiple datasets |
| Statistics | bellapy data stats |
get_stats() |
Dataset analysis (size, formats, dupes) |
| PII Scrubbing | bellapy data clean |
clean_dataset() |
Remove emails, phones, SSNs, API keys |
| Sanitization | bellapy data clean |
sanitize_content() |
Clean spam, emojis, broken text |
| Format Conversion | bellapy data convert |
convert_format() |
OpenAI โ HuggingFace โ Simple |
| Train/Test Split | bellapy data split |
split_dataset() |
Ratio-based splitting with shuffle |
| Sampling | Python only | sample_dataset() |
Random or ratio-based sampling |
| Stratified Sampling | Python only | stratified_sample() |
Length-balanced sampling |
| Length Filtering | Python only | filter_by_length() |
Filter by min/max character count |
| Pattern Filtering | Python only | filter_by_pattern() |
Regex-based filtering |
| Quality Filtering | Python only | filter_by_quality() |
Remove short, repetitive, URL-heavy |
| Custom Filtering | Python only | filter_custom() |
Your own filter function |
| Format Validation | Python only | validate_format() |
Check and fix format issues |
| Duplicate Analysis | Python only | check_duplicates_detailed() |
Detailed duplicate report |
Phase 2: Training (Coming Soon)
- Modal backend utilities
- Model-agnostic trainer
- Config management
- Training CLI
Phase 3: DPO Collection (Coming Soon)
- DPO session management
- Preference collection interface
- Analysis tools
- Interactive CLI
Phase 4: Inference (Coming Soon)
- Model caching with LoRA
- Conversation history
- Generation utilities
๐ Full Documentation
Command Reference
bellapy data dedupe <file> [-o OUTPUT] [-q]
Remove duplicates using MD5 hashing
bellapy data merge <output> <file1> <file2> ... [--no-dedupe] [-q]
Combine multiple JSONL files
bellapy data stats <file>
Show dataset statistics (total, duplicates, formats, lengths)
bellapy data clean <file> [-o OUTPUT] [--no-pii] [--no-sanitize] [-q]
Clean dataset with PII scrubbing and sanitization
bellapy data convert <file> [-o OUTPUT] -f FORMAT [--assistant-key KEY] [-q]
Convert between formats (messages, simple, openai, hf)
bellapy data split <file> [-r RATIO] [--no-shuffle] [-q]
Split into train/test sets
PII Detection
Coverage: Pattern-based detection for common PII types. Not ML-based.
What it catches reliably:
- Emails โ
[EMAIL](standard formats) - Phone numbers โ
[PHONE](US 10-digit, some international) - SSNs โ
[SSN](XXX-XX-XXXX format) - Credit cards โ
[CREDIT_CARD] - IP addresses โ
[IP] - URLs โ
[URL] - API keys โ
[API_KEY](standard patterns) - Private keys โ
[PRIVATE_KEY] - Passwords โ
[PASSWORD](in common formats) - ZIP codes โ
[ZIP] - MAC addresses โ
[MAC_ADDR]
Limitations:
- International phone formats may vary
- Novel API key formats require pattern updates
- Context-dependent PII (names, addresses) not detected
Always verify: Review scrubbed output before sharing datasets publicly.
Format Support
Input formats:
{"user": "Hello", "assistant": "Hi"}
{"user": "Hello", "EzrA": "Hi"}
{"messages": [{"role": "user", "content": "Hello"}, {"role": "assistant", "content": "Hi"}]}
Output formats:
messages- OpenAI/HF format with role-based messagessimple- Simple user/assistant key-value pairsopenai- OpenAI fine-tuning formathf- HuggingFace datasets format
โก Performance Notes
- Deduplication: MD5 hashing, O(n) single pass, streaming processing
- Large files (>1M lines): Minimal memory overhead via streaming
- Tested on: Datasets up to 500K examples without issues
- Memory efficient: Processes files line-by-line, not loading entire dataset into RAM
For datasets >10M examples, consider splitting before processing or using sampling.
๐ป Installation
Recommended (Most Users)
git clone https://github.com/JuiceB0xC0de/bellapy.git
cd bellapy
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
pip install -e .
With Training Dependencies
pip install -e ".[training]"
Development Install
pip install -e ".[dev]"
For advanced installation options (PyPI, training dependencies, development setup), see INSTALL.md.
Verify Installation
bellapy --version
bellapy data --help
๐ Project Structure
bellapy/
โโโ bellapy/
โ โโโ data/ # Data processing
โ โ โโโ processors.py # Dedupe, merge, stats, split
โ โ โโโ cleaning.py # PII scrubbing, sanitization
โ โ โโโ formats.py # Format conversion
โ โโโ cli/ # Command-line interface
โ โโโ training/ # Training utilities (Phase 2)
โ โโโ dpo/ # DPO collection (Phase 3)
โ โโโ inference/ # Model inference (Phase 4)
โโโ examples/ # Copy-paste examples
โโโ templates/ # Config templates
โโโ tests/ # Test suite (in development)
Testing Note: Basic tests cover core data operations. Users should validate pipelines on their own datasets before production use.
๐ Examples
Check out examples/ for real-world usage:
examples/clean_dataset.py- Full cleaning workflowexamples/merge_multiple_datasets.py- Combining sourcesexamples/prepare_for_training.py- OpenAI/HF preparationexamples/advanced_filtering.py- Sampling and filtering techniques
โ ๏ธ Common Mistakes
Don't do this:
# โ Piping large datasets through multiple commands
cat huge.jsonl | command1 | command2 # Memory explosion
# โ
Do this instead
bellapy data dedupe huge.jsonl -o step1.jsonl
bellapy data clean step1.jsonl -o step2.jsonl
Don't do this:
# โ Loading entire file into memory
with open('data.jsonl') as f:
data = json.load(f) # Boom on large files
# โ
Do this instead
from bellapy.data import deduplicate
deduplicate('data.jsonl', 'output.jsonl') # Streaming
Don't do this:
# โ Overwriting your only copy
bellapy data clean dataset.jsonl -o dataset.jsonl
# โ
Do this instead
bellapy data clean dataset.jsonl -o dataset_clean.jsonl
๐ง Troubleshooting
"File not found" errors:
- Use absolute paths or verify current directory with
pwd - Check file extensions (.jsonl required for most commands)
"Invalid JSON" errors:
- Run
bellapy data stats <file>to identify broken lines - Use Python's
validate_format()to auto-fix common issues
Performance degradation:
- Large files? Use
sample_dataset()for testing first - Memory issues? Check file size and consider splitting
- Slow processing? Ensure you're not loading entire file into memory
PII not detected:
- Pattern-based detection has limitations (see PII Detection section)
- Always manually verify scrubbed output
- Contribute new patterns via PR if you find gaps
๐จ Why This Exists
Built from frustration.
After the 50th time copying deduplicate.py between projects, I built this. It's the library I wish existed when I started.
Not a framework. No complicated configs. No inheritance hierarchies. Just utilities that do one thing well.
Real code from real projects:
- Cleaned datasets for fine-tuning workflows (Llama 3.2, Qwen 2.5, Dolphin 2.9, and others)
- Processed 15,000+ DPO training examples
- Merged hundreds of conversation datasets
- Scrubbed PII from production data
Model names listed as examples of use cases, not endorsements or affiliations.
If you've ever thought "I wrote this before," this is for you.
๐ธ Design Philosophy
Against: Frameworks that lock you in For: Tools that get out of your way
Against: "One true way" abstractions For: Sharp utilities you can compose
Against: Hiding complexity For: Transparent operations you can verify
Built by someone who breaks systems to understand them. Shared because knowledge held is dead knowledge.
๐ค Contributing
This is a personal library, but PRs are welcome for:
- Bug fixes with test cases
- New PII detection patterns (with examples)
- Format converters for common ML frameworks
- Performance improvements with benchmarks
See CONTRIBUTING.md for full guidelines.
What we don't accept:
- Framework abstractions
- Unrelated features
- Breaking changes without migration paths
๐ License
MIT License - See LICENSE
๐บ๏ธ Roadmap
v1.0.0 (Current) - Production Data Processing โ
- Deduplication, merging, stats
- PII scrubbing and sanitization
- Format conversion
- Train/test splitting
- Advanced filtering & sampling
- Quality validation
v1.1.0 (Planned) - Training Utilities
- Modal backend helpers
- Model-agnostic trainer
- Config management
v1.2.0 (Planned) - DPO Collection
- Session management
- Interactive CLI
- Analysis tools
v1.3.0 (Planned) - Inference
- Model caching
- LoRA support
- Generation utilities
๐ฎ Feedback
Found a bug? Want a feature? Open an issue.
Built by someone who got tired of copy/pasting the same scripts.
For everyone who's ever searched for "that deduplication script from 3 months ago."
Stop rewriting. Start using bellapy.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bellapy-1.0.0.tar.gz.
File metadata
- Download URL: bellapy-1.0.0.tar.gz
- Upload date:
- Size: 32.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5c13034a9e62fd6c4df93e77b0dad62078cb66303800594bc1eab7158bcb2d7
|
|
| MD5 |
bcb9a9da6c7112f07c4e355cfdd0d6e4
|
|
| BLAKE2b-256 |
bc35a0f57d73d7812366ff339d04ea5a38c06171e870758556ea4e727d961019
|
File details
Details for the file bellapy-1.0.0-py3-none-any.whl.
File metadata
- Download URL: bellapy-1.0.0-py3-none-any.whl
- Upload date:
- Size: 33.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68a008e16f37847001559920c70e7f7ddc53078338401e8ff98d4b310beea45d
|
|
| MD5 |
71f25f3da6ac23bef088b2f852d26fb0
|
|
| BLAKE2b-256 |
6fe6b8ba8f9069d3bc4d36ac5905ce8a803bb15cd4fccc67d59d893f4877fc51
|