Spaces:
Sleeping
Sleeping
File size: 12,469 Bytes
d5aaf43 ba222bb 786f9d6 ba222bb 52e5df1 a2fadca ba222bb 786f9d6 865ad03 ba222bb 0c907be ba222bb 786f9d6 ba222bb d5aaf43 ba222bb 786f9d6 ba222bb 786f9d6 5872c96 786f9d6 5872c96 786f9d6 5872c96 786f9d6 c39e972 786f9d6 c39e972 5872c96 c39e972 786f9d6 c39e972 bccfe43 5c5f011 bccfe43 c39e972 bccfe43 c39e972 bccfe43 c39e972 bccfe43 5c5f011 bccfe43 c39e972 bccfe43 786f9d6 52e5df1 786f9d6 ba222bb 786f9d6 ba222bb 786f9d6 ba222bb 786f9d6 ba222bb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
import gradio as gr
import os
import spaces
from transformers import GemmaTokenizer, AutoModelForCausalLM
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
from threading import Thread
from langchain_community.vectorstores.faiss import FAISS
from langchain_huggingface import HuggingFaceEmbeddings
from huggingface_hub import snapshot_download
# Set an environment variable
HF_TOKEN = os.environ.get("HF_TOKEN", None)
MODEL_NAME_OR_PATH = 'StevenChen16/llama3-8b-Lawyer'
# MODEL_NAME_OR_PATH = 'nvidia/Llama3-ChatQA-1.5-8B'
DESCRIPTION = '''
<div style="display: flex; align-items: center; justify-content: center; text-align: center;">
<a href="https://wealthwizards.org/" target="_blank">
<img src="./images/logo.png" alt="Wealth Wizards Logo" style="width: 60px; height: auto; margin-right: 10px;">
</a>
<div style="display: inline-block; text-align: left;">
<h1 style="font-size: 36px; margin: 0;">AI Lawyer</h1>
<a href="https://wealthwizards.org/" target="_blank" style="text-decoration: none; color: inherit;">
<p style="font-size: 16px; margin: 0;">wealth wizards</p>
</a>
</div>
</div>
'''
LICENSE = """
<p/>
---
Built with model "StevenChen16/Llama3-8B-Lawyer", based on "meta-llama/Meta-Llama-3-8B"
"""
PLACEHOLDER = """
<div style="padding: 30px; text-align: center; display: flex; flex-direction: column; align-items: center;">
<h1 style="font-size: 28px; margin-bottom: 2px; opacity: 0.55;">AI Lawyer</h1>
<p style="font-size: 18px; margin-bottom: 2px; opacity: 0.65;">Ask me anything about US and Canada law...</p>
</div>
"""
css = """
h1 {
text-align: center;
display: block;
}
#duplicate-button {
margin: auto;
color: white;
background: #1565c0;
border-radius: 100vh;
}
"""
# Load the tokenizer and model
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME_OR_PATH)
model = AutoModelForCausalLM.from_pretrained(MODEL_NAME_OR_PATH, device_map="auto") # to("cuda:0")
terminators = [
tokenizer.eos_token_id,
tokenizer.convert_tokens_to_ids("<|eot_id|>")
]
def create_embedding_model(model_name):
"""Create embedding model instance"""
return HuggingFaceEmbeddings(
model_name=model_name,
model_kwargs={'trust_remote_code': True}
)
embedding_model = create_embedding_model('intfloat/multilingual-e5-large-instruct')
try:
print("Downloading vector store from HuggingFace Hub...")
# Download FAISS files from HuggingFace Hub
repo_path = snapshot_download(
repo_id="StevenChen16/laws.faiss",
repo_type="model"
)
print("Loading vector store...")
# Load the vector store from downloaded files
vector_store = FAISS.load_local(
folder_path=repo_path,
embeddings=embedding_model,
allow_dangerous_deserialization=True
)
print("Vector store loaded successfully")
except Exception as e:
raise RuntimeError(f"Failed to load vector store from HuggingFace Hub: {str(e)}")
background_prompt = '''
As an AI legal assistant, you are a highly trained expert in U.S. and Canadian law. Your purpose is to provide accurate, comprehensive, and professional legal information to assist users with a wide range of legal questions. When answering questions, you should actively ask questions to obtain more information, analyze from different perspectives, and explain your reasoning process to the user.
In addition to providing general legal advice and analysis, you are also capable of assisting clients with drafting and reviewing standardized contracts and legal documents. However, your primary role is still to provide personalized legal guidance through interactive conversations with clients.
Please adhere to the following guidelines:
1. Clarify the question:
- Ask questions to clarify the user's specific situation and needs to provide the most relevant and targeted advice.
- However, if the user has already provided sufficient background information, avoid excessively pressing for details. Focus on understanding the core of the issue, rather than unnecessary minutiae.
2. Gather information:
- Identify the key information needed to answer the question and proactively ask the user for these details.
- When gathering information, be sure to identify which details are directly relevant to the legal analysis of the case. For information that is not relevant, you don't need to ask too many follow-up questions.
- If the user indicates that they have provided all relevant information, accept this and do not continue to demand more details.
3. Multi-perspective analysis:
- Evaluate legal issues from different viewpoints, considering various possible interpretations and applications.
- Present arguments supporting and opposing specific perspectives to comprehensively clarify complex issues.
- In your analysis, strive to balance comprehensiveness and conciseness. Provide thorough analysis, but also ensure that the user can easily understand and absorb the information.
4. Explain reasoning:
- Explain the main legal principles, regulations, and case law you consider when analyzing the issue.
- Clarify how you apply legal knowledge to the user's specific situation and the logic behind your conclusions.
- When explaining your reasoning, use clear and concise language, avoiding excessive length or repetition.
5. Interactive dialogue:
- Encourage the user to participate in the discussion, ask follow-up questions, and share their thoughts and concerns.
- Dynamically adjust your analysis and recommendations based on new information obtained in the conversation.
- In your interactions, be attentive to the user's needs and concerns. If they express satisfaction or indicate that they don't require more information, respect their wishes.
6. Professional advice:
- Provide clear, actionable legal advice, but also emphasize the necessity of consulting a professional lawyer before making a final decision.
- If clients wish to speak with a lawyer, you can introduce our team (WealthWizards), which consists of lawyers with different specializations and orientations.
- When providing advice, use language that is easy to understand and communicate with a tone of empathy and care. Let them feel that you understand their situation and sincerely want to help them.
7. Assistance with standardized contracts and legal documents:
- When clients request assistance with drafting or reviewing standardized contracts and legal documents, provide guidance and support to the best of your abilities.
- Analyze the client's needs and requirements, and offer suggestions on appropriate contract templates or clauses to include.
- Review drafted documents for potential legal issues or areas that may need improvement, and provide constructive feedback.
- However, always remind clients that while you can assist with drafting and review, final documents should still be reviewed and approved by a licensed attorney.
Please remember that your role is to provide general legal information and analysis, but also to actively guide and interact with the user during the conversation in a personalized and professional manner. If you feel that necessary information is missing to provide targeted analysis and advice, take the initiative to ask until you believe you have sufficient details. However, also be mindful to avoid over-inquiring or disregarding the user's needs and concerns.
When assisting with standardized contracts and documents, aim to provide value-added services while still maintaining the importance of attorney review. Your contract assistance should be a supplement to, not a replacement for, the interactive legal guidance that is your primary function.
Now, please guide me step by step to describe the legal issues I am facing, according to the above requirements.
'''
def query_vector_store(vector_store: FAISS, query, k=4, relevance_threshold=0.8):
"""
Query similar documents from vector store.
"""
retriever = vector_store.as_retriever(search_type="similarity_score_threshold",
search_kwargs={"score_threshold": relevance_threshold, "k": k})
similar_docs = retriever.invoke(query)
context = [doc.page_content for doc in similar_docs]
# Join the context list into a single string
return " ".join(context) if context else ""
@spaces.GPU(duration=120)
def chat_llama3_8b(message: str,
history: list,
temperature=0.6,
max_new_tokens=4096
) -> str:
"""
Generate a streaming response using the LLaMA model.
Args:
message (str): The current user message
history (list): List of previous conversation turns
temperature (float): Sampling temperature (0.0 to 1.0)
max_new_tokens (int): Maximum number of tokens to generate
Returns:
str: Generated response with citations if available
"""
# try:
# 1. Get relevant citations from vector store
citation = query_vector_store(vector_store, message, k=4, relevance_threshold=0.7)
# 2. Format conversation history
conversation = []
for user, assistant in history:
conversation.extend([
{"role": "user", "content": str(user)},
{"role": "assistant", "content": str(assistant)}
])
# 3. Construct the final prompt
final_message = ""
if citation:
final_message = f"{background_prompt}\nBased on these references:\n{citation}\nPlease answer: {message}"
else:
final_message = f"{background_prompt}\n{message}"
conversation.append({"role": "user", "content": final_message})
# 4. Prepare model inputs
input_ids = tokenizer.apply_chat_template(
conversation,
return_tensors="pt"
).to(model.device)
# 5. Setup streamer
streamer = TextIteratorStreamer(
tokenizer,
timeout=10.0,
skip_prompt=True,
skip_special_tokens=True
)
# 6. Configure generation parameters
generation_config = {
"input_ids": input_ids,
"streamer": streamer,
"max_new_tokens": max_new_tokens,
"do_sample": temperature > 0,
"temperature": temperature,
"eos_token_id": terminators
}
# 7. Generate in a separate thread
thread = Thread(target=model.generate, kwargs=generation_config)
thread.start()
# 8. Stream the output
accumulated_text = []
final_chunk = False
for text_chunk in streamer:
accumulated_text.append(text_chunk)
current_response = "".join(accumulated_text)
# Check if this is the last chunk
try:
next_chunk = next(iter(streamer))
accumulated_text.append(next_chunk)
except (StopIteration, RuntimeError):
final_chunk = True
# Add citations on the final chunk if they exist
if final_chunk and citation:
formatted_citations = "\n\nReferences:\n" + "\n".join(
f"[{i+1}] {cite.strip()}"
for i, cite in enumerate(citation.split('\n'))
if cite.strip()
)
current_response += formatted_citations
yield current_response
# except Exception as e:
# error_message = f"An error occurred: {str(e)}"
# print(error_message) # For logging
# yield error_message
# Gradio block
chatbot=gr.Chatbot(height=600, placeholder=PLACEHOLDER, label='Gradio ChatInterface')
with gr.Blocks(fill_height=True, css=css) as demo:
gr.Markdown(DESCRIPTION)
gr.ChatInterface(
fn=chat_llama3_8b,
chatbot=chatbot,
fill_height=True,
examples=[
['What are the key differences between a sole proprietorship and a partnership?'],
['What legal steps should I take if I want to start a business in the US?'],
['Can you explain the concept of "duty of care" in negligence law?'],
['What are the legal requirements for obtaining a patent in Canada?'],
['How can I protect my intellectual property when sharing my idea with potential investors?']
],
cache_examples=False,
)
gr.Markdown(LICENSE)
if __name__ == "__main__":
demo.launch() |