ChatBotLI2Klein / utils.py
alexkueck's picture
Update utils.py
52f3750
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Tuple, Type
import logging
import json
import os
import datetime
#import time
import hashlib
import csv
import requests
import re
import html
import torch
import sys
import gc
from pygments.lexers import guess_lexer, ClassNotFound
import gradio as gr
from pygments import highlight
from pygments.lexers import guess_lexer,get_lexer_by_name
from pygments.formatters import HtmlFormatter
import transformers
from transformers import AutoTokenizer, AutoModelForCausalLM, GPT2Tokenizer, GPT2LMHeadModel
#import auto-gptq
#from auto-gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
from transformers import LlamaForCausalLM, LlamaTokenizer
def reset_state():
return [], [], "Reset Done"
def reset_textbox():
return gr.update(value=""),""
def cancel_outputing():
return "Stop Done"
def transfer_input(inputs):
textbox = reset_textbox()
return (
inputs,
gr.update(value=""),
gr.Button.update(visible=True),
)
def is_stop_word_or_prefix(s: str, stop_words: list) -> bool:
for stop_word in stop_words:
if s.endswith(stop_word):
return True
for i in range(1, len(stop_word)):
if s.endswith(stop_word[:i]):
return True
return False
def generate_prompt_with_history(text, history, tokenizer, max_length=2048):
#prompt = "The following is a conversation between a human and an AI assistant named Baize (named after a mythical creature in Chinese folklore). Baize is an open-source AI assistant developed by UCSD and Sun Yat-Sen University. The human and the AI assistant take turns chatting. Human statements start with [|Human|] and AI assistant statements start with [|AI|]. The AI assistant always provides responses in as much detail as possible, and in Markdown format. The AI assistant always declines to engage with topics, questions and instructions related to unethical, controversial, or sensitive issues. Complete the transcript in exactly that format.\n[|Human|]Hello!\n[|AI|]Hi!"
prompt = "Das folgende ist eine Unterhaltung in deutsch zwischen einem Menschen und einem KI-Assistenten, der Baize genannt wird. Baize ist ein open-source KI-Assistent, der von UCSD entwickelt wurde. Der Mensch und der KI-Assistent chatten abwechselnd miteinander in deutsch. Die Antworten des KI Assistenten sind immer so ausführlich wie möglich und in Markdown Schreibweise und in deutscher Sprache. Wenn nötig übersetzt er sie ins Deutsche. Die Antworten des KI-Assistenten vermeiden Themen und Antworten zu unethischen, kontroversen oder sensiblen Themen. Die Antworten sind immer sehr höflich formuliert..\n[|Human|]Hallo!\n[|AI|]Hi!"
history = ["\n[|Human|]{}\n[|AI|]{}".format(x[0],x[1]) for x in history]
history.append("\n[|Human|]{}\n[|AI|]".format(text))
history_text = ""
flag = False
for x in history[::-1]:
if tokenizer(prompt+history_text+x, return_tensors="pt")['input_ids'].size(-1) <= max_length:
history_text = x + history_text
flag = True
else:
break
#print(history)
if flag:
return prompt+history_text,tokenizer(prompt+history_text, return_tensors="pt")
else:
return None
def load_tokenizer_and_model(base_model,load_8bit=False):
if torch.cuda.is_available():
device = "cuda"
else:
device = "cpu"
tokenizer = AutoTokenizer.from_pretrained(base_model, use_fast = True)
if device == "cuda":
model = AutoModelForCausalLM.from_pretrained(
base_model,
load_in_8bit=load_8bit,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
else:
model = AutoModelForCausalLM.from_pretrained(
base_model, device_map={"": device}, low_cpu_mem_usage=True, trust_remote_code=True
)
#if not load_8bit:
#model.half() # seems to fix bugs for some users.
model.eval()
return tokenizer,model,device
def load_tokenizer_and_model_Baize(base_model, load_8bit=True):
if torch.cuda.is_available():
device = "cuda"
else:
device = "cpu"
tokenizer = LlamaTokenizer.from_pretrained(base_model, add_eos_token=True, use_auth_token=True)
model = LlamaForCausalLM.from_pretrained(base_model, load_in_8bit=True, device_map="auto")
return tokenizer,model, device
def load_tokenizer_and_model_gpt2(base_model,load_8bit=False):
if torch.cuda.is_available():
device = "cuda"
else:
device = "cpu"
tokenizer = GPT2Tokenizer.from_pretrained(base_model, use_fast = True)
if device == "cuda":
model = GPT2LMHeadModel.from_pretrained(
base_model,
load_in_8bit=load_8bit,
torch_dtype=torch.float16,
device_map="auto",
)
else:
model = AutoModelForCausalLM.from_pretrained(
base_model, device_map={"": device}, low_cpu_mem_usage=True
)
#if not load_8bit:
#model.half() # seems to fix bugs for some users.
model.eval()
return tokenizer,model,device
def load_tokenizer_and_model_bloke_gpt(base_model, model_basename):
use_triton = False
if torch.cuda.is_available():
device = "cuda"
else:
device = "cpu"
tokenizer = AutoTokenizer.from_pretrained(base_model, use_fast=True)
model = AutoGPTQForCausalLM.from_quantized(base_model,
model_basename=model_basename,
use_safetensors=True,
trust_remote_code=False,
device="cuda:0",
use_triton=use_triton,
quantize_config=None)
return tokenizer,model,device
# Greedy Search
def greedy_search(input_ids: torch.Tensor,
model: torch.nn.Module,
tokenizer: transformers.PreTrainedTokenizer,
stop_words: list,
max_length: int,
temperature: float = 1.0,
top_p: float = 1.0,
top_k: int = 25) -> Iterator[str]:
generated_tokens = []
past_key_values = None
current_length = 1
for i in range(max_length):
with torch.no_grad():
if past_key_values is None:
outputs = model(input_ids)
else:
outputs = model(input_ids[:, -1:], past_key_values=past_key_values)
logits = outputs.logits[:, -1, :]
past_key_values = outputs.past_key_values
# apply temperature
logits /= temperature
probs = torch.softmax(logits, dim=-1)
# apply top_p
probs_sort, probs_idx = torch.sort(probs, dim=-1, descending=True)
probs_sum = torch.cumsum(probs_sort, dim=-1)
mask = probs_sum - probs_sort > top_p
probs_sort[mask] = 0.0
# apply top_k
#if top_k is not None:
# probs_sort1, _ = torch.topk(probs_sort, top_k)
# min_top_probs_sort = torch.min(probs_sort1, dim=-1, keepdim=True).values
# probs_sort = torch.where(probs_sort < min_top_probs_sort, torch.full_like(probs_sort, float(0.0)), probs_sort)
probs_sort.div_(probs_sort.sum(dim=-1, keepdim=True))
next_token = torch.multinomial(probs_sort, num_samples=1)
next_token = torch.gather(probs_idx, -1, next_token)
input_ids = torch.cat((input_ids, next_token), dim=-1)
generated_tokens.append(next_token[0].item())
text = tokenizer.decode(generated_tokens)
yield text
if any([x in text for x in stop_words]):
del past_key_values
del logits
del probs
del probs_sort
del probs_idx
del probs_sum
gc.collect()
return
def convert_to_markdown(text):
text = text.replace("$","&#36;")
def replace_leading_tabs_and_spaces(line):
new_line = []
for char in line:
if char == "\t":
new_line.append("&#9;")
elif char == " ":
new_line.append("&nbsp;")
else:
break
return "".join(new_line) + line[len(new_line):]
markdown_text = ""
lines = text.split("\n")
in_code_block = False
for line in lines:
if in_code_block is False and line.startswith("```"):
in_code_block = True
markdown_text += f"{line}\n"
elif in_code_block is True and line.startswith("```"):
in_code_block = False
markdown_text += f"{line}\n"
elif in_code_block:
markdown_text += f"{line}\n"
else:
line = replace_leading_tabs_and_spaces(line)
line = re.sub(r"^(#)", r"\\\1", line)
markdown_text += f"{line} \n"
return markdown_text
class State:
interrupted = False
def interrupt(self):
self.interrupted = True
def recover(self):
self.interrupted = False
shared_state = State()