Spaces:
Paused
Paused
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import os | |
from huggingface_hub import login | |
import gradio as gr | |
#from transformers import pipeline | |
import torch | |
from utils import * | |
from presets import * | |
from transformers import Trainer, TrainingArguments | |
import numpy as np | |
import evaluate | |
import pandas as pd | |
import sklearn | |
from sklearn.model_selection import train_test_split | |
from sklearn.metrics import accuracy_score, recall_score, precision_score, f1_score | |
##################################################### | |
#Hilfsfunktionen für das Training | |
##################################################### | |
#Datensets in den Tokenizer schieben... | |
def tokenize_function(examples): | |
return tokenizer(examples["text"]) | |
#Funktion, die den gegebenen Text aus dem Datenset gruppiert | |
def group_texts(examples): | |
# Concatenate all texts. | |
concatenated_examples = {k: sum(examples[k], []) for k in examples.keys()} | |
total_length = len(concatenated_examples[list(examples.keys())[0]]) | |
# We drop the small remainder, we could add padding if the model supported it instead of this drop, you can | |
# customize this part to your needs. | |
total_length = (total_length // block_size) * block_size | |
# Split by chunks of max_len. | |
result = { | |
k: [t[i : i + block_size] for i in range(0, total_length, block_size)] | |
for k, t in concatenated_examples.items() | |
} | |
result["labels"] = result["input_ids"].copy() | |
return result | |
################################################################################### | |
################################################################################### | |
#Access-Token (in Secrets) | |
#aus den Secrets importieren (siehe Setting zu diesem Space) | |
#login(token=os.environ["HF_ACCESS_TOKEN"]) | |
#Modelle und Tokenizer | |
#Alternativ mit beliebigen Modellen: | |
#base_model = "project-baize/baize-v2-7b" #load_8bit = False (in load_tokenizer_and_model) | |
#base_model = "TheBloke/airoboros-13B-HF" #load_8bit = False (in load_tokenizer_and_model) | |
base_model = "EleutherAI/gpt-neo-1.3B" #load_8bit = False (in load_tokenizer_and_model) | |
#base_model = "TheBloke/airoboros-13B-HF" #load_8bit = True | |
tokenizer,model,device = load_tokenizer_and_model(base_model, False) | |
#tokenizer.add_special_tokens({'pad_token': '[PAD]'}) #not necessary with fast Toekenizers like GPT2 | |
dataset_neu = daten_laden("alexkueck/tis") | |
#dataset_neu = daten_laden("EleutherAI/pile") | |
############################################# | |
#Vorbereiten für das Training der neuen Daten | |
############################################# | |
#alles zusammen auf das neue datenset anwenden - batched = True und 4 Prozesse, um die Berechnung zu beschleunigen. Die "text" - Spalte braucht man anschließend nicht mehr, daher weglassen. | |
tokenized_datasets = dataset_neu.map(tokenize_function, batched=True, num_proc=4, remove_columns=["id","text"]) | |
#wenn man zum Trainieren erstmal nur einen kleinen Datensatz nehem möchte: | |
#small_train_dataset = tokenized_datasets["train"].shuffle(seed=42).select(range(1000)) | |
#small_eval_dataset = tokenized_datasets["test"].shuffle(seed=42).select(range(1000)) | |
print (tokenized_datasets["train"][4]) | |
#den Text nun zusammenführen (concatenieren) und anschließend in kleine Häppchen aufteilen (block_size=128), die verarbeitet werden können | |
#das macht die map-Funktion und das Attribut batched = True | |
#man könnte das weglassen, wenn jeder Satz einzeln gegeben wurde in den Texten... | |
#eigentlich nimmt man als block_size die max. Länge in der das Model trainiert wurde -> könnte aber zu groß sein für den RAm der GPU , daher hier 128 gewählt | |
# block_size = tokenizer.model_max_length | |
block_size = 128 | |
#nochmal die map-Funktion auf das bereits tokenisierte Datenset anwenden | |
#die bereits tokenisierten Datensatze ändern sich dadurch: die samples enthalten nun Mengen aus block_size Tokens | |
lm_datasets = tokenized_datasets.map( | |
group_texts, | |
batched=True, | |
batch_size=1000, | |
num_proc=4, | |
) | |
print ("lm datasets") | |
#die Daten wurden nun "gereinigt" und für das Model vorbereitet. | |
#z.B. anschauen mit: tokenizer.decode(lm_datasets["train"][1]["input_ids"]) | |
#################################################### | |
#Training | |
#################################################### | |
#Training Args | |
batch_size = 2 | |
training_args = TrainingArguments( | |
output_dir="alexkueck/test-tis-1", | |
overwrite_output_dir = 'True', | |
per_device_train_batch_size=batch_size, #batch_size = 2 for full training | |
per_device_eval_batch_size=batch_size, | |
evaluation_strategy = "epoch", #oder steps | |
learning_rate=2e-5, | |
weight_decay=0.01, | |
save_total_limit = 2, | |
#predict_with_generate=True, | |
#logging_steps=2, # set to 1000 for full training | |
#save_steps=16, # set to 500 for full training | |
#eval_steps=4, # set to 8000 for full training | |
#warmup_steps=1, # set to 2000 for full training | |
#max_steps=16, # delete for full training | |
# overwrite_output_dir=True, | |
#save_total_limit=1, | |
#fp16=True, | |
save_strategy = "no", | |
load_best_model_at_end=False, | |
#push_to_hub=True, | |
) | |
print ("training args") | |
############################################ | |
#def trainieren_neu(name): | |
#Trainer zusammenstellen | |
trainer = Trainer( | |
model=model, | |
args=training_args, | |
train_dataset=lm_datasets["train"], | |
eval_dataset=lm_datasets["test"], | |
#tokenizer=tokenizer, | |
#compute_metrics=compute_metrics, | |
) | |
print ("trainer") | |
#trainer ausführen | |
#trainer.train() | |
#Wenn man vom letzten checkpoint aus weiter trainieren möchte: trainer.train(resume_from_checkpoint=True) | |
print("trained!!!!!") | |
################## | |
#Evaluate the new Model | |
print("Evaluate:") | |
trainer.evaluate() | |
print("Done Eval") | |
############################ | |
#Test | |
############################ | |
print("Test") | |
text = "Was ist Tis?" | |
''' | |
encoding = tokenizer(text, return_tensors="pt") | |
encoding = {k: v.to(trainer.model.device) for k,v in encoding.items()} | |
outputs = trainer.model(**encoding) | |
logits = outputs.logits | |
print(logits.shape) | |
#greedy_output = model.generate(input_ids, max_length=50) | |
print("Output:\n" ) | |
#print(tokenizer.decode(outputs[0], skip_special_tokens=True)) | |
''' | |
print("Save to Space") | |
#trainer.save_model("alexkueck/test-tis-1") | |
print("done") | |
''' | |
##################################### | |
#Push to Hub | |
print("push to hub") | |
login(token=os.environ["HF_WRITE_TOKEN"]) | |
trainer.push_to_hub("test-tis-1") | |
''' | |
tokenizer.push_to_hub("test-tis-1") | |
print("done") | |
############################################## | |
#Testen des fine-tuned Modells | |
print("Predict") | |
login(token=os.environ["HF_ACCESS_TOKEN"]) | |
model_neu = "test-tis-1" | |
tokenizer_neu,model_neu, device_neu = load_tokenizer_and_model(model_neu, False) | |
antwort = predict(model_neu, tokenizer_neu, device_neu, "Was ist Tis?", [["Tis", ""]], top_p=5, | |
temperature=0.8, | |
max_length_tokens=1024, | |
max_context_length_tokens=2048,) | |
print(antwort) | |
print("done Predict") | |
####################################################################### | |
#Darstellung mit Gradio | |
''' | |
with gr.Blocks() as demo: | |
name = gr.Textbox(label="Model") | |
output = gr.Textbox(label="Output Box") | |
start_btn = gr.Button("Start") | |
start_btn.click(fn=trainieren_neu, inputs=name, outputs=output, api_name="trainieren_neu") | |
demo.queue(default_enabled=True).launch(debug=True) | |
''' |