Metadata-Version: 2.4
Name: dqntrain
Version: 0.1.0
Summary: Headless, config-driven fine-tuning for LLMs on cloud GPUs
Home-page: https://github.com/dqntrain/dqntrain
Author: dqntrain
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: unsloth>=2025.1.0
Requires-Dist: trl>=0.15.0
Requires-Dist: transformers>=4.48.0
Requires-Dist: datasets>=3.0.0
Requires-Dist: accelerate>=1.0.0
Requires-Dist: peft>=0.14.0
Requires-Dist: bitsandbytes>=0.45.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: huggingface_hub>=0.27.0
Requires-Dist: matplotlib>=3.7.0
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# dqntrain

Headless, config-driven fine-tuning for LLMs on cloud GPUs.

A programmatic fine-tuning toolkit inspired by Unsloth Studio's workflow, built for headless environments like **Kaggle**, **Google Colab**, and remote servers. No GUI required — just YAML/JSON recipes, clean Python APIs, and automatic GPU-aware defaults.

## Quick Start (Kaggle / Colab Notebook)

### 1. Install

```python
%%capture
!pip install dqntrain
```

### 2. Define a Config

```python
from dqntrain import auto_config_for_model

config = auto_config_for_model("unsloth/Qwen2.5-7B-Instruct-bnb-4bit")
config.training.num_train_epochs = 1
config.dataset.path = "yahma/alpaca-cleaned"
config.export.formats = ["lora", "gguf"]
```

### 3. Train

```python
from dqntrain import (
    ModelLoader, DatasetBuilder, DQNTrainer,
    TrainingMonitor, ModelExporter
)

loader = ModelLoader(config)
model, tokenizer = loader.load()
model = loader.apply_lora()

dataset = DatasetBuilder(config).build()

monitor = TrainingMonitor()
trainer = DQNTrainer(config, monitor=monitor)
trainer.create_trainer(model, tokenizer, dataset)
trainer.train()
monitor.plot()

ModelExporter(config).export(model, tokenizer)
```

That's it. The entire pipeline in ~15 lines.

## Features

| Capability | Description |
|---|---|
| **Model presets** | `auto_config_for_model()` detects your GPU and sets 4-bit, batch size, seq length |
| **LoRA / QLoRA** | `LoRAConfig` dataclass or YAML recipes |
| **Dataset formats** | JSON, JSONL, CSV, HuggingFace datasets, conversations — auto-detected |
| **Live monitoring** | Loss/LR/GPU tracking with matplotlib plots + JSONL logs |
| **Multi-format export** | LoRA, merged 16-bit, GGUF, Ollama Modelfile — in one call |
| **Headless-first** | No browser, no desktop UI — built for notebooks and servers |

## Project Structure

```
dqntrain/
├── dqntrain/
│   ├── config.py          # YAML/JSON recipes + auto GPU presets
│   ├── models.py          # Model loader + LoRA applier
│   ├── data.py            # Dataset builder (JSON/CSV/HF/conversations)
│   ├── trainer.py         # SFTTrainer wrapper with cloud paths
│   ├── observability.py   # Live metrics, plots, JSONL logging
│   ├── export.py          # GGUF, merged, Ollama, Hub push
│   └── utils.py           # Environment detection + GPU info
├── configs/
│   ├── quick_lora.yaml    # T4-optimized 4-bit recipe
│   └── full_finetune.yaml # P100+ 16-bit recipe
└── notebooks/
    └── kaggle_template.ipynb  # Ready-to-run Kaggle notebook
```

## Config Recipes

Save a YAML file and pass it to `load_config()`:

```yaml
model:
  name: "unsloth/Qwen2.5-7B-Instruct-bnb-4bit"
  max_seq_length: 2048
  load_in_4bit: true

lora:
  r: 16
  lora_alpha: 32
  target_modules: [q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj]

training:
  num_train_epochs: 1
  per_device_train_batch_size: 1
  gradient_accumulation_steps: 4
  learning_rate: 2.0e-4
  output_dir: "./outputs"

dataset:
  path: "yahma/alpaca-cleaned"
  instruction_column: "instruction"
  response_column: "output"

export:
  formats: [lora, gguf]
  quantization: "q4_k_m"
```

## Supported Dataset Formats

`DatasetBuilder` auto-detects:

- **HuggingFace datasets** (`dataset.path = "yahma/alpaca-cleaned"`)
- **JSON / JSONL** files with `instruction`/`response` or `conversations` arrays
- **CSV** files with text columns
- **In-memory lists** of dicts

## GPU-Aware Defaults

`auto_config_for_model()` inspects your GPU and adjusts:

- `load_in_4bit` — forced on for T4 (15 GB), optional on P100/V100
- `per_device_train_batch_size` — smaller for big models
- `max_seq_length` — capped to fit VRAM
- `gradient_accumulation_steps` — scaled up to maintain effective batch size

## Export Formats

`ModelExporter` can produce any combination of:

- `lora` — LoRA adapter (smallest, fastest to save)
- `merged` / `safetensors` — Full 16-bit merged model
- `gguf` — Quantized GGUF for llama.cpp / Ollama
- `ollama` — `Modelfile` ready for `ollama create`

## CLI Usage

```bash
# Install deps
pip install dqntrain

# Run from a config file
dqntrain --config configs/quick_lora.yaml

# Override model and dataset
dqntrain --model unsloth/Phi-4 --dataset my_data.jsonl --epochs 2
```

## Kaggle-Specific Tips

1. **Enable Internet** in notebook settings for `pip install` and HF downloads.
2. **Persist outputs** — everything in `/kaggle/working` survives the session.
3. **Save Versions** — click "Save Version" → "Run" to execute headlessly. Logs still write to `/kaggle/working`.
4. **Dataset inputs** — upload custom JSON/CSV via Kaggle Datasets, then reference them with `config.dataset.path = "/kaggle/input/your-dataset/file.json"`.

## License

MIT. This package depends on Unsloth (Apache 2.0 core), TRL, and Transformers.
