|
from __future__ import annotations |
|
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Tuple, Type |
|
import logging |
|
import json |
|
import os |
|
import datetime |
|
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 |
|
|
|
|
|
def reset_state(): |
|
return [], [], "Resettato" |
|
|
|
def reset_textbox(): |
|
return gr.update(value=""),"" |
|
|
|
def cancel_outputing(): |
|
return "Cancellato" |
|
|
|
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 = "Conversazione tra un umano e una IA. Baize è sviluppato da UCSD e Sun Yat-Sen University. [|Human|] [|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!" |
|
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 |
|
if flag: |
|
return prompt+history_text,tokenizer(prompt+history_text, return_tensors="pt") |
|
else: |
|
return None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tokenizer = AutoTokenizer.from_pretrained("EleutherAI/gpt-neo-1.3B") |
|
model = AutoModelForCausalLM.from_pretrained("EleutherAI/gpt-neo-1.3B") |
|
|
|
|
|
def load_tokenizer_and_model(base_model,load_8bit=False): |
|
base_model = "EleutherAI/gpt-neo-1.3B" |
|
if torch.cuda.is_available(): |
|
device = "cuda" |
|
else: |
|
device = "cpu" |
|
|
|
tokenizer = AutoTokenizer.from_pretrained(base_model, use_fast = False) |
|
if device == "cuda": |
|
model = AutoModelForCausalLM.from_pretrained( |
|
base_model, |
|
|
|
|
|
device_map="auto", |
|
) |
|
else: |
|
model = AutoModelForCausalLM.from_pretrained( |
|
base_model, device_map={"": device}, low_cpu_mem_usage=True |
|
) |
|
|
|
|
|
|
|
|
|
model.eval() |
|
return tokenizer,model,device |
|
|
|
|
|
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 |
|
|
|
|
|
logits /= temperature |
|
|
|
probs = torch.softmax(logits, dim=-1) |
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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("$","$") |
|
def replace_leading_tabs_and_spaces(line): |
|
new_line = [] |
|
|
|
for char in line: |
|
if char == "\t": |
|
new_line.append("	") |
|
elif char == " ": |
|
new_line.append(" ") |
|
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() |