Spaces:
Runtime error
Runtime error
Commit ·
a945e6f
1
Parent(s): fe58e47
Second commit
Browse files- .DS_Store +0 -0
- LICENSE +21 -0
- app.py +0 -7
- llama.py +130 -0
- llama_chat_format.py +49 -0
- models/llama-2-7b-chat.ggmlv3.q4_K_M.bin +1 -0
- requirements.txt +6 -0
.DS_Store
ADDED
|
Binary file (6.15 kB). View file
|
|
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2023 Martin Thissen
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
app.py
DELETED
|
@@ -1,7 +0,0 @@
|
|
| 1 |
-
import gradio as gr
|
| 2 |
-
|
| 3 |
-
def greet(name):
|
| 4 |
-
return "Hello " + name + "!!"
|
| 5 |
-
|
| 6 |
-
iface = gr.Interface(fn=greet, inputs="text", outputs="text")
|
| 7 |
-
iface.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
llama.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import gradio as gr
|
| 3 |
+
import fire
|
| 4 |
+
from enum import Enum
|
| 5 |
+
from threading import Thread
|
| 6 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 7 |
+
from auto_gptq import AutoGPTQForCausalLM
|
| 8 |
+
from llama_cpp import Llama
|
| 9 |
+
from huggingface_hub import hf_hub_download
|
| 10 |
+
from transformers import TextIteratorStreamer
|
| 11 |
+
from llama_chat_format import format_to_llama_chat_style
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
# class syntax
|
| 15 |
+
class Model_Type(Enum):
|
| 16 |
+
gptq = 1
|
| 17 |
+
ggml = 2
|
| 18 |
+
full_precision = 3
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def get_model_type(model_name):
|
| 22 |
+
if "gptq" in model_name.lower():
|
| 23 |
+
return Model_Type.gptq
|
| 24 |
+
elif "ggml" in model_name.lower():
|
| 25 |
+
return Model_Type.ggml
|
| 26 |
+
else:
|
| 27 |
+
return Model_Type.full_precision
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def create_folder_if_not_exists(folder_path):
|
| 31 |
+
if not os.path.exists(folder_path):
|
| 32 |
+
os.makedirs(folder_path)
|
| 33 |
+
|
| 34 |
+
# running on gpu? you are using either full precission model or gptq quantization
|
| 35 |
+
def initialize_gpu_model_and_tokenizer(model_name, model_type):
|
| 36 |
+
if model_type == Model_Type.gptq:
|
| 37 |
+
model = AutoGPTQForCausalLM.from_quantized(model_name, device_map="auto", use_safetensors=True, use_triton=False)
|
| 38 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
| 39 |
+
else:
|
| 40 |
+
model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto", token=True)
|
| 41 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name, token=True)
|
| 42 |
+
return model, tokenizer
|
| 43 |
+
|
| 44 |
+
# this is if you run on CPU - then you are using the ggml model type
|
| 45 |
+
def init_auto_model_and_tokenizer(model_name, model_type, file_name=None):
|
| 46 |
+
model_type = get_model_type(model_name)
|
| 47 |
+
|
| 48 |
+
if Model_Type.ggml == model_type:
|
| 49 |
+
models_folder = "./models"
|
| 50 |
+
create_folder_if_not_exists(models_folder)
|
| 51 |
+
file_path = hf_hub_download(repo_id=model_name, filename=file_name, local_dir=models_folder)
|
| 52 |
+
model = Llama(file_path, n_ctx=4096)
|
| 53 |
+
tokenizer = None
|
| 54 |
+
else:
|
| 55 |
+
model, tokenizer = initialize_gpu_model_and_tokenizer(model_name, model_type=model_type)
|
| 56 |
+
return model, tokenizer
|
| 57 |
+
|
| 58 |
+
# Chatbot implementation based upon: https://www.gradio.app/guides/creating-a-custom-chatbot-with-blocks
|
| 59 |
+
def run_ui(model, tokenizer, is_chat_model, model_type):
|
| 60 |
+
|
| 61 |
+
#Blocks are made with a with clause, and any component created inside this clause is automatically added to the app.
|
| 62 |
+
with gr.Blocks() as demo:
|
| 63 |
+
|
| 64 |
+
#Gradio components created in the app - Chatbot, textbox and button
|
| 65 |
+
chatbot = gr.Chatbot()
|
| 66 |
+
msg = gr.Textbox()
|
| 67 |
+
clear = gr.Button("Clear")
|
| 68 |
+
|
| 69 |
+
# This implementation offers chat streaming. How:
|
| 70 |
+
# First, we can stream responses so the user doesn’t have to wait as long for a message to be generated.
|
| 71 |
+
# Second, we can have the user message appear immediately in the chat history, while the chatbot’s response is being generated.
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
#The first method user() updates the chatbot with the user message and clears the input field. This method also makes the input field non interactive so that the user can’t send another message while the chatbot is responding. Because we want this to happen instantly, we set queue=False, which would skip any queue had it been enabled. The chatbot’s history is appended with (user_message, None), the None signifying that the bot has not responded.
|
| 75 |
+
def user(user_message, history):
|
| 76 |
+
return "", history + [[user_message, None]]
|
| 77 |
+
|
| 78 |
+
#The second method, bot() updates the chatbot history with the bot’s response. Instead of creating a new message, we just replace the previously-created None message with the bot’s response. Finally, we construct the message character by character and yield the intermediate outputs as they are being constructed. Gradio automatically turns any function with the yield keyword into a streaming output interface.
|
| 79 |
+
def bot(history):
|
| 80 |
+
# it is required by llama implementation to format the chats before using (in case of using the finetuned chat model)
|
| 81 |
+
# see for details: https://github.com/facebookresearch/llama
|
| 82 |
+
if is_chat_model:
|
| 83 |
+
instruction = format_to_llama_chat_style(history)
|
| 84 |
+
else:
|
| 85 |
+
instruction = history[-1][0]
|
| 86 |
+
|
| 87 |
+
print('instruction',instruction)
|
| 88 |
+
#this is the model generated text
|
| 89 |
+
history[-1][1] = ""
|
| 90 |
+
kwargs = dict(temperature=0.6, top_p=0.9)
|
| 91 |
+
if model_type == Model_Type.ggml:
|
| 92 |
+
kwargs["max_tokens"] = 512
|
| 93 |
+
for chunk in model(prompt=instruction, stream=True, **kwargs):
|
| 94 |
+
token = chunk["choices"][0]["text"]
|
| 95 |
+
history[-1][1] += token
|
| 96 |
+
yield history
|
| 97 |
+
|
| 98 |
+
else:
|
| 99 |
+
streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, Timeout=5)
|
| 100 |
+
inputs = tokenizer(instruction, return_tensors="pt").to(model.device)
|
| 101 |
+
kwargs["max_new_tokens"] = 512
|
| 102 |
+
kwargs["input_ids"] = inputs["input_ids"]
|
| 103 |
+
kwargs["streamer"] = streamer
|
| 104 |
+
thread = Thread(target=model.generate, kwargs=kwargs)
|
| 105 |
+
thread.start()
|
| 106 |
+
|
| 107 |
+
for token in streamer:
|
| 108 |
+
history[-1][1] += token
|
| 109 |
+
yield history
|
| 110 |
+
|
| 111 |
+
# when a user submits their message, we now chain three event events with .then():
|
| 112 |
+
|
| 113 |
+
msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(bot, chatbot, chatbot)
|
| 114 |
+
clear.click(lambda: None, None, chatbot, queue=False)
|
| 115 |
+
|
| 116 |
+
demo.queue()
|
| 117 |
+
demo.launch(share=True, debug=True)
|
| 118 |
+
|
| 119 |
+
def main(model_name="", file_name=""):
|
| 120 |
+
model_name = "TheBloke/Llama-2-7B-Chat-GGML" #"TheBloke/Llama-2-13B-GPTQ"
|
| 121 |
+
file_name = "llama-2-7b-chat.ggmlv3.q4_K_M.bin"
|
| 122 |
+
|
| 123 |
+
is_chat_model = 'chat' in model_name.lower()
|
| 124 |
+
model_type = get_model_type(model_name)
|
| 125 |
+
|
| 126 |
+
model, tokenizer = init_auto_model_and_tokenizer(model_name, model_type, file_name)
|
| 127 |
+
run_ui(model, tokenizer, is_chat_model, model_type)
|
| 128 |
+
|
| 129 |
+
if __name__ == '__main__':
|
| 130 |
+
fire.Fire(main)
|
llama_chat_format.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
BOS, EOS = "<s>", "</s>"
|
| 2 |
+
B_INST, E_INST = "[INST]", "[/INST]"
|
| 3 |
+
B_SYS, E_SYS = "<<SYS>>\n", "\n<</SYS>>\n\n"
|
| 4 |
+
DEFAULT_SYSTEM_PROMPT = """\
|
| 5 |
+
You are a vegetarian diet assistant. You promote vegetarian diet as a healthier alternative to meat-based diet.
|
| 6 |
+
|
| 7 |
+
You mainly communicate with teenagers. Make your language style more youthful, but still be serious.
|
| 8 |
+
|
| 9 |
+
Do not make gender assumptions, do not use words like 'bro' or 'girl'.
|
| 10 |
+
|
| 11 |
+
Be conversational, ask questions to your users as part of your response.
|
| 12 |
+
|
| 13 |
+
Detect and adapt to your user's communication style.
|
| 14 |
+
|
| 15 |
+
You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.
|
| 16 |
+
|
| 17 |
+
If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information."""
|
| 18 |
+
|
| 19 |
+
def format_to_llama_chat_style(history) -> str:
|
| 20 |
+
# history has the following structure:
|
| 21 |
+
# - dialogs
|
| 22 |
+
# --- instruction
|
| 23 |
+
# --- response (None for the most recent dialog)
|
| 24 |
+
prompt = ""
|
| 25 |
+
|
| 26 |
+
# this takes everything except the last message.
|
| 27 |
+
for i, dialog in enumerate(history[:-1]):
|
| 28 |
+
instruction, response = dialog[0], dialog[1]
|
| 29 |
+
# prepend system instruction before first instruction
|
| 30 |
+
if i == 0:
|
| 31 |
+
instruction = f"{B_SYS}{DEFAULT_SYSTEM_PROMPT}{E_SYS}" + instruction
|
| 32 |
+
else:
|
| 33 |
+
# the tokenizer automatically adds a bos_token during encoding,
|
| 34 |
+
# for this reason the bos_token is not added for the first instruction
|
| 35 |
+
prompt += BOS
|
| 36 |
+
prompt += f"{B_INST} {instruction.strip()} {E_INST} {response.strip()} " + EOS
|
| 37 |
+
# new instruction from the user - this is really just the user message ['user','bot']
|
| 38 |
+
new_instruction = history[-1][0].strip()
|
| 39 |
+
# the tokenizer automatically adds a bos_token during encoding,
|
| 40 |
+
# for this reason the bos_token is not added for the first instruction
|
| 41 |
+
if len(history) > 1:
|
| 42 |
+
prompt += BOS
|
| 43 |
+
else:
|
| 44 |
+
# prepend system instruction before first instruction
|
| 45 |
+
new_instruction = f"{B_SYS}{DEFAULT_SYSTEM_PROMPT}{E_SYS}" + new_instruction
|
| 46 |
+
|
| 47 |
+
prompt += f"{B_INST} {new_instruction} {E_INST}"
|
| 48 |
+
|
| 49 |
+
return prompt
|
models/llama-2-7b-chat.ggmlv3.q4_K_M.bin
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
../../../../.cache/huggingface/hub/models--TheBloke--Llama-2-7B-Chat-GGML/blobs/0652a35e3d8cde0632e03a97924b51adf3945b22c7e000da1d21e81e52ac75e5
|
requirements.txt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
transformers==4.31.0
|
| 2 |
+
auto-gptq==0.3.0
|
| 3 |
+
langchain==0.0.237
|
| 4 |
+
gradio==3.37.0
|
| 5 |
+
llama-cpp-python==0.1.73
|
| 6 |
+
fire==0.5.0
|