-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.py
More file actions
145 lines (123 loc) · 5.18 KB
/
Copy pathmain.py
File metadata and controls
145 lines (123 loc) · 5.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import os
import time
import torch
from torch.utils.data import DataLoader
# Import our modules
from dual_mode_data_preparation import (
prepare_dataset_for_training_chunked,
convert_single_to_multi_format,
create_mixed_dataset
)
from dual_mode_model_training import (
create_dual_decoder_model,
train_dual_model,
run_example_queries
)
def main():
# Configuration settings
config = {
# Model paths
"model_dir1": "./DeepSeek-R1-Distill-Qwen-1.5B",
"model_dir2": "./Llama-3.2-1B",
"dataset_path": "data.jsonl",
"output_dir": "./model_outputs",
# Model configuration
"fusion_output_dim": 2048, # Larger fusion layer for cross-attention
"freeze_base_models": True,
"max_length": 1000,
# Training configuration
"train_batch_size": 1,
"eval_batch_size": 1,
"learning_rate": 5e-5,
"epochs": 3,
"patience": 15,
"accumulation_steps": 16,
"train_val_split": 0.8,
"seed": 42,
"use_multi_gpu": True,
# Dataset loading configuration
"data_workers": 12, # Number of parallel workers
"data_batch_size": 1000, # Process this many samples in each parallel batch
"use_threads": True, # Use threads instead of processes
"dataset_cache_dir": "./dataset_cache", # Caching directory
"use_cached_dataset": True, # Whether to use/save cached preprocessed dataset
# Data preparation (optional)
"prepare_mixed_dataset": False, # Whether to create a mixed dataset
"single_format_file": "single_data.jsonl", # Path to single-task format file
"multi_format_file": "multi_data.jsonl", # Path to multi-task format file
"mixed_output_file": "mixed_data.jsonl", # Path to save the mixed dataset
"single_task_ratio": 0.5, # Ratio of single-task samples in mixed dataset
"processing_chunk_size": 100000, # Number of examples to process at once
"data_batch_size": 1000, # Size of batches for parallel processing
"create_multitask_samples": True, # Enable multi-task conversion
"multitask_ratio": 0.1, # 30% of samples become multi-task
}
# Set random seed for reproducibility
torch.manual_seed(config["seed"])
if torch.cuda.is_available():
torch.cuda.manual_seed_all(config["seed"])
# Create output directory if not exists
os.makedirs(config["output_dir"], exist_ok=True)
# Optional: Create a mixed dataset if requested
if config["prepare_mixed_dataset"]:
print("Preparing mixed dataset...")
# Step 1: Convert original data to multi-task format if needed
convert_single_to_multi_format(
config["single_format_file"],
config["multi_format_file"],
mode="shuffle" # Options: duplicate, alternate, shuffle
)
# Step 2: Create mixed dataset with both formats
create_mixed_dataset(
config["single_format_file"],
config["multi_format_file"],
config["mixed_output_file"],
ratio=config["single_task_ratio"]
)
# Update the dataset path
config["dataset_path"] = config["mixed_output_file"]
# Prepare dataset for training
print("Preparing dataset...")
train_dataloader, val_dataloader, tokenizer1, tokenizer2 = prepare_dataset_for_training_chunked(config)
# Create the dual decoder model
dual_model = create_dual_decoder_model(config, tokenizer1, tokenizer2)
# Set up optimizer - we only optimize parameters that require gradients
trainable_params = [p for p in dual_model.parameters() if p.requires_grad]
optimizer = torch.optim.AdamW(trainable_params, lr=config["learning_rate"])
# Train the model
print("Starting training...")
train_dual_model(
model=dual_model,
train_dataloader=train_dataloader,
val_dataloader=val_dataloader,
optimizer=optimizer,
tokenizer1=tokenizer1,
tokenizer2=tokenizer2,
epochs=config["epochs"],
patience=config["patience"],
accumulation_steps=config["accumulation_steps"],
fp16=True,
output_dir=config["output_dir"],
device_map=dual_model.device_map
)
# Save the final model
print("Saving model...")
# Move all components to CPU for saving to avoid GPU memory issues
dual_model.to("cpu")
final_model_path = os.path.join(config["output_dir"], "dual_model_final.pt")
torch.save(dual_model.state_dict(), final_model_path)
print(f"Final model saved to {final_model_path}")
# Run example queries
print("\nRunning example queries...")
# Get device map for inference
device_map = None
if torch.cuda.device_count() > 1 and config["use_multi_gpu"]:
device_map = {
'model1': 'cuda:1',
'model2': 'cuda:0',
'fusion': 'cuda:0'
}
run_example_queries(dual_model, tokenizer1, tokenizer2, device_map)
print("Example queries complete!")
if __name__ == "__main__":
main()