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 [], [], "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!" 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 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 = False) if device == "cuda": model = AutoModelForCausalLM.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 # 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("$","$") 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()