#!/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 ##################################################### #Hilfsfunktionen für das training ##################################################### #Datensets in den Tokenizer schieben... def tokenize_function(examples): return tokenizer(examples["text"]) #neues Model testen nach dem Training ######################################################################## #Zm Test einen Text zu generieren... def predict(text, history, top_p=0.3, temperature=0.9, max_length_tokens=1024, max_context_length_tokens=2048,): if text=="": return try: model except: return print("fehler model") inputs = generate_prompt_with_history(text,history, tokenizer,max_length=max_context_length_tokens) if inputs is None: return print("Fehler inputs") else: prompt,inputs=inputs begin_length = len(prompt) input_ids = inputs["input_ids"][:,-max_context_length_tokens:].to(device) torch.cuda.empty_cache() #torch.no_grad() bedeutet, dass für die betreffenden tensoren keine Ableitungen berechnet werden bei der backpropagation #hier soll das NN ja auch nicht geändert werden 8backprop ist nicht nötig), da es um interference-prompts geht! print("torch.no_grad") with torch.no_grad(): ausgabe = "" #die vergangenen prompts werden alle als Tupel in history abgelegt sortiert nach 'Human' und 'AI'- dass sind daher auch die stop-words, die den jeweils nächsten Eintrag kennzeichnen for x in greedy_search(input_ids,model,tokenizer,stop_words=["[|Human|]", "[|AI|]"],max_length=max_length_tokens,temperature=temperature,top_p=top_p): if is_stop_word_or_prefix(x,["[|Human|]", "[|AI|]"]) is False: if "[|Human|]" in x: x = x[:x.index("[|Human|]")].strip() if "[|AI|]" in x: x = x[:x.index("[|AI|]")].strip() x = x.strip() ausgabe = ausgabe + x # a, b= [[y[0],convert_to_markdown(y[1])] for y in history]+[[text, convert_to_markdown(x)]],history + [[text,x]] print("Erzeuge") yield print(Ausgabe) if shared_state.interrupted: shared_state.recover() try: print("Erfolg") return ausgabe except: pass del input_ids gc.collect() torch.cuda.empty_cache() try: print("erfolg") return ausgabe except: pass ################################################################################### ################################################################################### #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 training_args = TrainingArguments( output_dir="alexkueck/spaces/LIFineTuned/", overwrite_output_dir = 'True', evaluation_strategy = "epoch", learning_rate=2e-5, weight_decay=0.01, save_total_limit = 2, 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() print("trained!!!!!") #in den Hub laden #trainer.push_to_hub("test-tis", use_auth_token=True) ############################ #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) print("Save to Space") trainer.save_model("alexkueck/spaces/LIFineTuned/") print("done") ##################################### #Push to Hub #print("push to hub") #login(token=os.environ["HF_ACCESS_TOKEN"]) #trainer.push_to_hub("alexkueck/model/finetune-tis") #print("done") ############################################## #Testen des fine-tuned Modells print("Predict") antwort = predict("Was ist Tis?", [["Tis", None]]) 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) '''