Spaces:
Sleeping
Sleeping
File size: 6,054 Bytes
b66afb2 16c09c6 3850a48 16c09c6 3850a48 16c09c6 068d18a 16c09c6 068d18a 16c09c6 068d18a 16c09c6 068d18a 16c09c6 068d18a 16c09c6 068d18a 16c09c6 068d18a 16c09c6 068d18a 16c09c6 068d18a 16c09c6 068d18a 16c09c6 |
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 |
from langchain.chains import create_history_aware_retriever, create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
from langchain.memory import ConversationBufferMemory
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings
from transformers import AutoTokenizer, pipeline ,AutoModelForSeq2SeqLM,AutoModelForCausalLM,GenerationConfig
from langchain_huggingface import HuggingFacePipeline
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.tools import Tool
from langchain.agents import initialize_agent, AgentType
from langdetect import detect
import re
import os
import warnings
import gradio as gr
warnings.filterwarnings('ignore')
from ctransformers import AutoModelForCausalLM, AutoTokenizer
from langchain.llms import CTransformers
BASE_PATH = os.getcwd()
INDEX_PATHS = {
"en": os.path.join(BASE_PATH, "faiss_index_en"),
"fr": os.path.join(BASE_PATH, "faiss_index_fr"),
}
embedding = HuggingFaceEmbeddings(model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
#retriever = FAISS.load_local(folder_path=path, embeddings=embedding,allow_dangerous_deserialization=True).as_retriever()
model = AutoModelForCausalLM.from_pretrained("TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF",
model_file="tinyllama-1.1b-chat-v1.0.Q4_0.gguf",model_type="llama"
)
llm = CTransformers(
model="TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF",
model_file="tinyllama-1.1b-chat-v1.0.Q4_0.gguf",
model_type="llama",
config={"max_new_tokens": 512, "temperature": 0.0,"context_length": 4096}
)
system_template = ("You are Bot — an intelligent assistant trained on cameroon penal code data."
"You exist to help individuals answer questions about the Cameroonian Penal Code."
" You always provide the source penal code section or article number, clear, compliant, and factual answers grounded in official penal code documentation."
"When given an law question and information, you explain all components."
"If a query is ambiguous or unsupported, you politely defer or recommend reviewing the relevant penal code manually."
"You do not speculate or make law interpretations — you clarify with precision and data.")
condense_question_prompt = ChatPromptTemplate.from_messages(
[
("system", system_template),
("placeholder", "{chat_history}"),
("human", "{input}"),
]
)
#history_aware_retriever = create_history_aware_retriever(
# llm, retriever, condense_question_prompt
#)
system_prompt = (
"You are an assistant for question-answering tasks. "
"Use the following pieces of retrieved context to answer "
"the question. If you don't know the answer, say that you "
"don't know. Use three sentences maximum and keep the "
"answer concise."
"\n\n"
"{context}"
)
from langchain.prompts import PromptTemplate
qa_prompt = PromptTemplate.from_template(
"You are a legal assistant. Use and highlight the following penal or article code number and context and conversation history to answer the current question.\n\n"
"Context:\n{context}\n\n"
"Conversation History:\n{chat_history}\n\n"
"Current Question:\n{input}\n"
"Answer:"
)
llm_chain = create_stuff_documents_chain(llm=llm, prompt=qa_prompt)
#rag_chain = create_retrieval_chain(history_aware_retriever, llm_chain)
# Preload retrievers once
retrievers = {
"en": FAISS.load_local(
folder_path=INDEX_PATHS["en"],
embeddings=embedding,
allow_dangerous_deserialization=True
).as_retriever(search_kwargs={"k": 2}),
"fr": FAISS.load_local(
folder_path=INDEX_PATHS["fr"],
embeddings=embedding,
allow_dangerous_deserialization=True
).as_retriever(search_kwargs={"k": 2}),
}
# Truncate long history
def truncate_history(chat_history, max_chars=1500):
total = 0
trimmed = []
for q, a in reversed(chat_history):
pair_len = len(q) + len(a)
if total + pair_len > max_chars:
break
trimmed.insert(0, (q, a))
total += pair_len
return trimmed
# Simpler, faster RAG function
def rag_tool_func(input_question: str, chat_history: list = None) -> str:
lang = detect(input_question)
lang = "fr" if lang == "fr" else "en"
retriever = retrievers[lang]
# Format chat history (optional, for prompt context)
chat_history = truncate_history(chat_history)
history_str = ""
if isinstance(chat_history, list):
for q, a in chat_history:
history_str += f"User: {q}\nAssistant: {a}\n"
rag_chain = create_retrieval_chain(retriever, create_stuff_documents_chain(llm=llm, prompt=qa_prompt))
result = rag_chain.invoke({
"input": input_question,
"chat_history": history_str
})
return result["answer"]
chat_history = [] # Global chat history
def chatbot_interface(user_input, history):
if history is None or not isinstance(history, list):
history = []
trimmed_history = truncate_history(history)
answer = rag_tool_func(user_input, trimmed_history)
history.append((user_input, answer))
return history, history # For chatbot + state
with gr.Blocks() as demo:
gr.Markdown("# 🇨🇲 Cameroon Penal Code Chatbot")
chatbot_ui = gr.Chatbot(label="Ask me anything about the Cameroon Penal Code")
with gr.Row():
question_box = gr.Textbox(placeholder="Ask a legal question...", label="Your question")
send_btn = gr.Button("Send")
chat_state = gr.State([])
send_btn.click(fn=chatbot_interface, inputs=[question_box, chat_state], outputs=[chatbot_ui, chat_state])
question_box.submit(fn=chatbot_interface, inputs=[question_box, chat_state], outputs=[chatbot_ui, chat_state])
if __name__ == "__main__":
demo.launch() |