初始化项目,由ModelHub XC社区提供模型
Model: zxc4wewewe/DarkGPT-model Source: Original Platform
This commit is contained in:
129
main.py
Normal file
129
main.py
Normal file
@@ -0,0 +1,129 @@
|
||||
import numpy as np
|
||||
import torch
|
||||
from datasets import load_dataset
|
||||
from transformers import (
|
||||
AutoTokenizer,
|
||||
AutoModelForCausalLM,
|
||||
TrainingArguments,
|
||||
Trainer,
|
||||
DataCollatorForLanguageModeling,
|
||||
)
|
||||
|
||||
# ─── Configuration ───────────────────────────────────────────────────────────
|
||||
MODEL_NAME = "zxc4wewewe/blackthinking" # lightweight model suitable for CPU
|
||||
MAX_LENGTH = 512 # max token length per example
|
||||
OUTPUT_DIR = "./results"
|
||||
NUM_EPOCHS = 3
|
||||
BATCH_SIZE = 2 # small batch for CPU training
|
||||
LEARNING_RATE = 5e-5
|
||||
LOGGING_STEPS = 50
|
||||
|
||||
# ─── 1. Load dataset from Hugging Face Hub ───────────────────────────────────
|
||||
dataset = load_dataset("zxc4wewewe/offsec")
|
||||
print(f"Train: {len(dataset['train'])} examples | Test: {len(dataset['test'])} examples")
|
||||
print(f"Columns: {dataset['train'].column_names}")
|
||||
|
||||
|
||||
# ─── 2. Format & tokenize ────────────────────────────────────────────────────
|
||||
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
|
||||
|
||||
# GPT-2 has no pad token by default — use eos_token
|
||||
if tokenizer.pad_token is None:
|
||||
tokenizer.pad_token = tokenizer.eos_token
|
||||
|
||||
|
||||
def format_and_tokenize(examples):
|
||||
"""Combine prompt + response into a single text and tokenize."""
|
||||
texts = [
|
||||
f"{prompt}{response}{tokenizer.eos_token}"
|
||||
for prompt, response in zip(examples["prompt"], examples["response"])
|
||||
]
|
||||
tokenized = tokenizer(
|
||||
texts,
|
||||
truncation=True,
|
||||
max_length=MAX_LENGTH,
|
||||
padding="max_length",
|
||||
)
|
||||
# For causal LM, labels = input_ids (the model learns to predict next token)
|
||||
tokenized["labels"] = tokenized["input_ids"].copy()
|
||||
return tokenized
|
||||
|
||||
|
||||
tokenized_dataset = dataset.map(
|
||||
format_and_tokenize,
|
||||
batched=True,
|
||||
remove_columns=dataset["train"].column_names,
|
||||
desc="Tokenizing",
|
||||
)
|
||||
|
||||
print(f"Tokenized train: {len(tokenized_dataset['train'])} examples")
|
||||
|
||||
|
||||
# ─── 3. Model ────────────────────────────────────────────────────────────────
|
||||
model = AutoModelForCausalLM.from_pretrained(MODEL_NAME)
|
||||
model.resize_token_embeddings(len(tokenizer))
|
||||
|
||||
data_collator = DataCollatorForLanguageModeling(
|
||||
tokenizer=tokenizer,
|
||||
mlm=False, # causal LM, not masked LM
|
||||
)
|
||||
|
||||
|
||||
# ─── 4. Training ─────────────────────────────────────────────────────────────
|
||||
training_args = TrainingArguments(
|
||||
output_dir=OUTPUT_DIR,
|
||||
overwrite_output_dir=True,
|
||||
num_train_epochs=NUM_EPOCHS,
|
||||
per_device_train_batch_size=BATCH_SIZE,
|
||||
per_device_eval_batch_size=BATCH_SIZE,
|
||||
eval_strategy="epoch",
|
||||
save_strategy="epoch",
|
||||
learning_rate=LEARNING_RATE,
|
||||
weight_decay=0.01,
|
||||
logging_dir="./logs",
|
||||
logging_steps=LOGGING_STEPS,
|
||||
load_best_model_at_end=True,
|
||||
save_total_limit=2,
|
||||
fp16=False, # CPU-only
|
||||
report_to="none",
|
||||
)
|
||||
|
||||
trainer = Trainer(
|
||||
model=model,
|
||||
args=training_args,
|
||||
train_dataset=tokenized_dataset["train"],
|
||||
eval_dataset=tokenized_dataset["test"],
|
||||
data_collator=data_collator,
|
||||
)
|
||||
|
||||
print("Starting training...")
|
||||
trainer.train()
|
||||
|
||||
# Save final model
|
||||
trainer.save_model(f"{OUTPUT_DIR}/final_model")
|
||||
tokenizer.save_pretrained(f"{OUTPUT_DIR}/final_model")
|
||||
print(f"Model saved to {OUTPUT_DIR}/final_model")
|
||||
|
||||
|
||||
# ─── 5. Inference ────────────────────────────────────────────────────────────
|
||||
def generate_response(prompt_text, max_new_tokens=256):
|
||||
"""Generate a response given a prompt."""
|
||||
inputs = tokenizer(prompt_text, return_tensors="pt")
|
||||
with torch.no_grad():
|
||||
output_ids = model.generate(
|
||||
**inputs,
|
||||
max_new_tokens=max_new_tokens,
|
||||
do_sample=True,
|
||||
temperature=0.7,
|
||||
top_p=0.9,
|
||||
pad_token_id=tokenizer.eos_token_id,
|
||||
)
|
||||
# Decode only the generated part (skip the prompt tokens)
|
||||
generated = output_ids[0][inputs["input_ids"].shape[1]:]
|
||||
return tokenizer.decode(generated, skip_special_tokens=True)
|
||||
|
||||
|
||||
# Example usage (uncomment to test after training):
|
||||
sample_prompt = dataset["test"][0]["prompt"]
|
||||
print("Prompt:", sample_prompt[:200], "...")
|
||||
print("Generated:", generate_response(sample_prompt))
|
||||
Reference in New Issue
Block a user