Files
DS-LLM-TEMPLATE-FINETUNING/README.md
T
2025-08-13 23:59:28 +00:00

727 lines
18 KiB
Markdown

# Fine-Tuning Task Framework
A comprehensive framework for fine-tuning Large Language Models (LLMs) across multiple task types including classification, completion, styling, and matching.
## Table of Contents
- [Overview](#overview)
- [Architecture](#architecture)
- [Task Types](#task-types)
- [Quick Start](#quick-start)
- [Configuration Guide](#configuration-guide)
- [Scripts & Commands](#scripts--commands)
- [Complete Workflows](#complete-workflows)
- [API Reference](#api-reference)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
## Overview
This framework provides a unified approach to fine-tuning LLMs for various NLP tasks. It's designed to be:
- **Task-Agnostic**: Same pipeline structure for different task types
- **Configuration-Driven**: YAML-based configuration for all parameters
- **Developer-Friendly**: Clear scripts and comprehensive logging
- **Production-Ready**: Built-in validation, error handling, and optimization
## Architecture
The framework follows a **modular pipeline architecture**:
```
Raw Data → Data Processing → Model Training → Inference/Evaluation
↓ ↓ ↓ ↓
JSONL/CSV HuggingFace Trained Ready for
Files Datasets Models Production
```
### Core Components
1. **Data Processors**: Convert raw data to training-ready formats
2. **Training Pipelines**: Task-specific training with optimization
3. **Inference Engines**: Production-ready text generation/classification
4. **Configuration Management**: YAML-based parameter control
5. **Utility Scripts**: Command-line interfaces for all operations
## Task Types
### 1. Classification Task
**Purpose**: Text classification, sentiment analysis, topic categorization
**Data Format**:
```jsonl
{"text": "I love this product!", "label": "positive"}
{"text": "This is terrible", "label": "negative"}
```
**Output**: Classification probabilities and predicted labels
**Use Cases**: Sentiment analysis, spam detection, content moderation
### 2. Completion Task
**Purpose**: Text generation, story completion, code generation
**Data Format**:
```jsonl
{"prompt": "Once upon a time", "completion": "there was a brave knight..."}
{"prompt": "def calculate_sum", "completion": "(numbers): return sum(numbers)"}
```
**Output**: Generated text continuations
**Use Cases**: Creative writing, code completion, content generation
### 3. Styling Task
**Purpose**: Style transfer, tone modification, writing style adaptation
**Data Format**:
```jsonl
{"text": "Hey there!", "styled_text": "Hello, how are you?"}
{"text": "I'm gonna go", "styled_text": "I will be going"}
```
**Output**: Text rewritten in target style
**Use Cases**: Formalization, casualization, domain adaptation
### 4. Matching Task
**Purpose**: Semantic similarity, question-answer matching, paraphrase detection
**Data Format**:
```jsonl
{"text1": "What is AI?", "text2": "Artificial Intelligence", "label": "similar"}
{"text1": "Weather today", "text2": "Cooking recipes", "label": "different"}
```
**Output**: Similarity scores or binary classifications
**Use Cases**: Search relevance, duplicate detection, semantic matching
## Quick Start
### Prerequisites
```bash
# Install dependencies
pip install -r requirements.txt
# Verify installation
python -c "import torch, transformers, datasets; print('✅ All packages installed')"
```
### Basic Workflow
```bash
# 1. Process data
python scripts/[task_type]/data_processor.py --config configs/[task_type]/[config].yaml
# 2. Train model
python scripts/[task_type]/train.py train --config configs/[task_type]/[config].yaml
# 3. Run inference
python scripts/[task_type]/inference.py infer --config configs/[task_type]/[config].yaml
```
## Configuration Guide
### YAML Structure
All configurations follow this hierarchical structure:
```yaml
# Task Configuration
task:
name: "task_type" # classification, completion, styling, matching
type: "specific_type" # e.g., "sentiment_analysis", "style_transfer"
# Data Configuration
data:
source: "custom" # "custom" or "huggingface"
data_path: "./data/raw/..." # Path to raw data
input_field: "text" # Field name for input
output_field: "label" # Field name for output
instruction: "Task instruction" # For instruction-following tasks
# Model Configuration
model:
name: "model_name" # HuggingFace model identifier
max_seq_length: 2048 # Maximum sequence length
dtype: null # Data type (auto-detected)
load_in_4bit: true # 4-bit quantization
# Training Configuration
training:
num_epochs: 3 # Training epochs
batch_size: 4 # Batch size
learning_rate: 2e-4 # Learning rate
warmup_steps: 5 # Warmup steps
max_steps: 60 # Maximum training steps
# Inference Configuration
inference:
batch_size: 32 # Inference batch size
max_new_tokens: 128 # Max tokens to generate
temperature: 0.8 # Sampling temperature
```
### Configuration Parameters
#### Data Processing Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `source` | string | "custom" | Data source type |
| `data_path` | string | required | Path to raw data file |
| `input_field` | string | "text" | Input field name |
| `output_field` | string | "label" | Output field name |
| `instruction` | string | task-specific | Task instruction |
| `data_format` | string | "jsonl" | Data file format |
| `max_length` | int | 256 | Maximum text length |
| `min_length` | int | 10 | Minimum text length |
| `clean_text` | boolean | true | Enable text cleaning |
| `lowercase` | boolean | false | Convert to lowercase |
#### Model Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `name` | string | required | HuggingFace model name |
| `max_seq_length` | int | 2048 | Maximum sequence length |
| `dtype` | string | null | Data type (auto-detected) |
| `load_in_4bit` | boolean | true | Enable 4-bit quantization |
| `token` | string | null | HuggingFace access token |
#### Training Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `num_epochs` | int | 1 | Number of training epochs |
| `batch_size` | int | 2 | Training batch size |
| `learning_rate` | float | 2e-4 | Learning rate |
| `weight_decay` | float | 0.01 | Weight decay |
| `warmup_steps` | int | 5 | Warmup steps |
| `max_steps` | int | 60 | Maximum training steps |
| `gradient_accumulation_steps` | int | 4 | Gradient accumulation |
#### LoRA Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `lora_r` | int | 16 | LoRA rank |
| `lora_alpha` | int | 16 | LoRA alpha |
| `lora_dropout` | float | 0 | LoRA dropout |
| `target_modules` | list | ["q_proj", "k_proj", "v_proj", "o_proj"] | Target modules for LoRA |
### Environment Variables
```bash
# HuggingFace token for gated models
export HF_TOKEN="hf_..."
# CUDA device selection
export CUDA_VISIBLE_DEVICES="0"
# Logging level
export LOG_LEVEL="INFO"
```
## Scripts & Commands
### Data Processing Scripts
#### Basic Usage
```bash
python scripts/[task_type]/data_processor.py --config configs/[task_type]/[config].yaml
```
#### Advanced Options
```bash
python scripts/[task_type]/data_processor.py \
--config configs/[task_type]/[config].yaml \
--max-samples 1000 \
--log-level DEBUG \
--create-hf-dataset \
--hf-dataset-path ./datasets/[task_name]
```
#### Command Line Arguments
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `--config` | string | required | YAML configuration file |
| `--max-samples` | int | all | Maximum samples to process |
| `--log-level` | string | "INFO" | Logging level |
| `--create-hf-dataset` | flag | false | Create HuggingFace dataset |
| `--hf-dataset-path` | string | auto | HuggingFace dataset path |
### Training Scripts
#### Basic Usage
```bash
python scripts/[task_type]/train.py train --config configs/[task_type]/[config].yaml
```
#### Advanced Options
```bash
python scripts/[task_type]/train.py train \
--config configs/[task_type]/[config].yaml \
--epochs 5 \
--batch-size 8 \
--learning-rate 1e-4 \
--max-steps 100
```
#### Command Line Arguments
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `--config` | string | required | YAML configuration file |
| `--epochs` | int | YAML value | Override training epochs |
| `--batch-size` | int | YAML value | Override batch size |
| `--learning-rate` | float | YAML value | Override learning rate |
| `--max-steps` | int | YAML value | Override max steps |
| `--output-dir` | string | YAML value | Override output directory |
### Inference Scripts
#### Basic Usage
```bash
python scripts/[task_type]/inference.py infer \
--config configs/[task_type]/[config].yaml \
--input-text "Your input text here"
```
#### Advanced Options
```bash
python scripts/[task_type]/inference.py infer \
--config configs/[task_type]/[config].yaml \
--input-text "Your input text here" \
--max-tokens 256 \
--temperature 0.7 \
--stream
```
#### Command Line Arguments
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `--config` | string | required | YAML configuration file |
| `--input-text` | string | required | Text to process |
| `--max-tokens` | int | 128 | Maximum tokens to generate |
| `--temperature` | float | 0.8 | Sampling temperature |
| `--stream` | flag | false | Enable streaming generation |
### Batch Processing
```bash
# Process multiple inputs from file
python scripts/[task_type]/inference.py batch \
--config configs/[task_type]/[config].yaml \
--input-file input.txt \
--output-file output.txt
```
### Interactive Mode
```bash
# Enter interactive mode for testing
python scripts/[task_type]/inference.py interactive \
--config configs/[task_type]/[config].yaml
```
## Complete Workflows
### Classification Task Workflow
#### 1. Data Preparation
```jsonl
# data/raw/classification/sentiment.jsonl
{"text": "I love this movie!", "label": "positive"}
{"text": "This is terrible", "label": "negative"}
{"text": "It's okay", "label": "neutral"}
```
#### 2. Configuration
```yaml
# configs/classification/sentiment.yaml
task:
name: "classification"
type: "sentiment_analysis"
data:
source: "custom"
data_path: "./data/raw/classification/sentiment.jsonl"
input_field: "text"
output_field: "label"
instruction: "Classify the sentiment of the following text"
model:
name: "microsoft/DialoGPT-medium"
max_seq_length: 512
training:
num_epochs: 3
batch_size: 8
learning_rate: 3e-5
```
#### 3. Execute Pipeline
```bash
# Process data
python scripts/classification/data_processor.py --config configs/classification/sentiment.yaml
# Train model
python scripts/classification/train.py train --config configs/classification/sentiment.yaml
# Run inference
python scripts/classification/inference.py infer \
--config configs/classification/sentiment.yaml \
--input-text "This product exceeded my expectations!"
```
### Styling Task Workflow
#### 1. Data Preparation
```jsonl
# data/raw/styling/formal.jsonl
{"text": "Hey there!", "styled_text": "Hello, how are you?"}
{"text": "I'm gonna go", "styled_text": "I will be going"}
{"text": "This is cool", "styled_text": "This is quite impressive"}
```
#### 2. Configuration
```yaml
# configs/styling/formal.yaml
task:
name: "styling"
type: "style_transfer"
data:
source: "custom"
data_path: "./data/raw/styling/formal.jsonl"
input_field: "text"
output_field: "styled_text"
instruction: "Rewrite the following text in a formal style"
model:
name: "unsloth/Meta-Llama-3.1-8B-Instruct-bnb-4bit"
max_seq_length: 2048
training:
num_epochs: 3
batch_size: 4
learning_rate: 2e-4
model_output_dir: "./models/styling"
```
#### 3. Execute Pipeline
```bash
# Process data
python scripts/styling/data_processor.py --config configs/styling/formal.yaml
# Train model
python scripts/styling/train.py train --config configs/styling/formal.yaml
# Run inference
python scripts/styling/inference.py infer \
--config configs/styling/formal.yaml \
--instruction "Rewrite in formal style" \
--input-text "Hey there! What's up?"
```
### Completion Task Workflow
#### 1. Data Preparation
```jsonl
# data/raw/completion/story.jsonl
{"prompt": "Once upon a time", "completion": "there was a brave knight who lived in a castle..."}
{"prompt": "The dragon roared", "completion": "and the ground shook beneath its massive feet..."}
```
#### 2. Configuration
```yaml
# configs/completion/story.yaml
task:
name: "completion"
type: "story_generation"
data:
source: "custom"
data_path: "./data/raw/completion/story.jsonl"
input_field: "prompt"
output_field: "completion"
model:
name: "gpt2-medium"
max_seq_length: 1024
training:
num_epochs: 2
batch_size: 16
learning_rate: 5e-5
```
#### 3. Execute Pipeline
```bash
# Process data
python scripts/completion/data_processor.py --config configs/completion/story.yaml
# Train model
python scripts/completion/train.py train --config configs/completion/story.yaml
# Run inference
python scripts/completion/inference.py infer \
--config configs/completion/story.yaml \
--input-text "The wizard cast a spell"
```
## API Reference
### Data Processing Classes
#### BaseDataProcessor
```python
class BaseDataProcessor:
def __init__(self, config: Dict[str, Any])
def load_and_preprocess(self) -> Tuple[Dict, Dict]
def validate_data(self, data: Dict) -> Tuple[bool, List[str]]
def save_data(self, data: Dict, output_path: str)
```
#### ClassificationDataProcessor
```python
class ClassificationDataProcessor(BaseDataProcessor):
def convert_to_classification_format(self, data: Dict) -> Dict
def create_label_mapping(self, labels: List[str]) -> Dict[str, int]
```
#### StylingDataProcessor
```python
class StylingDataProcessor(BaseDataProcessor):
def convert_to_alpaca_format(self, data: Dict) -> Dict
def format_for_training(self, data: Dict) -> Dict
```
### Training Classes
#### BaseTrainer
```python
class BaseTrainer:
def __init__(self, config: Dict[str, Any])
def load_model_and_tokenizer(self)
def setup_training(self, dataset: Dataset)
def train(self, dataset_path: str) -> Dict
def save_model(self)
```
#### ClassificationTrainer
```python
class ClassificationTrainer(BaseTrainer):
def setup_classification_head(self)
def compute_metrics(self, eval_pred) -> Dict
```
#### StylingTrainer
```python
class StylingTrainer(BaseTrainer):
def setup_lora(self)
def format_dataset(self, dataset: Dataset) -> Dataset
```
### Inference Classes
#### BaseInference
```python
class BaseInference:
def __init__(self, config: Dict[str, Any])
def load_model_and_tokenizer(self)
def preprocess_input(self, input_text: str) -> torch.Tensor
def postprocess_output(self, output: torch.Tensor) -> str
```
#### ClassificationInference
```python
class ClassificationInference(BaseInference):
def classify(self, text: str) -> Dict[str, float]
def batch_classify(self, texts: List[str]) -> List[Dict]
```
#### StylingInference
```python
class StylingInference(BaseInference):
def style_transfer(self, text: str, instruction: str) -> str
def generate_text(self, instruction: str, input_text: str) -> str
```
## Troubleshooting
### Common Issues
#### 1. Model Loading Errors
**Error**: `FileNotFoundError: ./models/[task_name]/*.json`
**Solution**:
- Verify model was trained successfully
- Check `model_output_dir` in YAML config
- Ensure model files exist in specified directory
#### 2. Memory Issues
**Error**: `CUDA out of memory`
**Solution**:
- Reduce `batch_size` in YAML config
- Enable `load_in_4bit: true`
- Use gradient accumulation
- Reduce `max_seq_length`
#### 3. Data Format Errors
**Error**: `KeyError: 'input_field'`
**Solution**:
- Verify field names in JSONL/CSV files
- Check `input_field` and `output_field` in YAML
- Ensure data format matches expected structure
#### 4. Training Convergence Issues
**Symptoms**: Loss not decreasing, poor model performance
**Solution**:
- Adjust learning rate (try 1e-5 to 5e-4)
- Increase training epochs
- Check data quality and quantity
- Verify label distribution (for classification)
### Debug Mode
Enable detailed logging:
```bash
export LOG_LEVEL="DEBUG"
python scripts/[task_type]/[script].py --log-level DEBUG
```
### Performance Optimization
#### Memory Optimization
```yaml
model:
load_in_4bit: true # 4-bit quantization
dtype: "float16" # Use float16 if supported
training:
gradient_accumulation_steps: 4 # Effective batch size = batch_size * steps
max_grad_norm: 1.0 # Gradient clipping
```
#### Speed Optimization
```yaml
training:
dataloader_num_workers: 4 # Parallel data loading
fp16: true # Mixed precision training
bf16: false # Disable bfloat16 if not supported
```
## Contributing
### Adding New Task Types
1. **Create task directory structure**:
```
pipelines/[new_task]/
├── __init__.py
├── data_processor.py
├── train.py
└── inference.py
scripts/[new_task]/
├── __init__.py
├── data_processor.py
├── train.py
└── inference.py
configs/[new_task]/
└── example.yaml
```
2. **Implement base classes**:
- Extend `BaseDataProcessor`
- Extend `BaseTrainer`
- Extend `BaseInference`
3. **Add configuration templates**:
- Define task-specific parameters
- Document all configuration options
4. **Update documentation**:
- Add task description to README
- Include usage examples
- Document configuration parameters
### Code Style
- Follow PEP 8 guidelines
- Use type hints for all functions
- Include comprehensive docstrings
- Add unit tests for new functionality
### Testing
```bash
# Run all tests
python -m pytest tests/
# Run specific task tests
python -m pytest tests/[task_type]/
# Run with coverage
python -m pytest --cov=pipelines tests/
```
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Support
- **Issues**: [GitHub Issues](https://github.com/your-repo/issues)
- **Discussions**: [GitHub Discussions](https://github.com/your-repo/discussions)
- **Documentation**: [Wiki](https://github.com/your-repo/wiki)
---
**Happy fine-tuning! 🚀**