国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

langchain-ChatGLM源碼閱讀:webui.py

這篇具有很好參考價值的文章主要介紹了langchain-ChatGLM源碼閱讀:webui.py。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

樣式定制

使用gradio設(shè)置頁面的視覺組件和交互邏輯,位于webui.py

import gradio as gr
import shutil

from chains.local_doc_qa import LocalDocQA
from configs.model_config import *
import nltk
import models.shared as shared
from models.loader.args import parser
from models.loader import LoaderCheckPoint
import os

nltk.data.path = [NLTK_DATA_PATH] + nltk.data.path
embedding_model_dict_list = list(embedding_model_dict.keys())

llm_model_dict_list = list(llm_model_dict.keys())

local_doc_qa = LocalDocQA()
# 記錄運(yùn)行日志到 CSV文件
flag_csv_logger = gr.CSVLogger()

block_css = """.importantButton {
    background: linear-gradient(45deg, #7e0570,#5d1c99, #6e00ff) !important;
    border: none !important;
}
.importantButton:hover {
    background: linear-gradient(45deg, #ff00e0,#8500ff, #6e00ff) !important;
    border: none !important;
}"""

webui_title = """
# ??langchain-ChatGLM WebUI??
?? [https://github.com/imClumsyPanda/langchain-ChatGLM](https://github.com/imClumsyPanda/langchain-ChatGLM)
"""
# 檢索知識庫
default_vs = get_vs_list()[0] if len(get_vs_list()) > 1 else "為空"
init_message = f"""歡迎使用 langchain-ChatGLM Web UI!

請?jiān)谟覀?cè)切換模式,目前支持直接與 LLM 模型對話或基于本地知識庫問答。

知識庫問答模式,選擇知識庫名稱后,即可開始問答,當(dāng)前知識庫{default_vs},如有需要可以在選擇知識庫名稱后上傳文件/文件夾至知識庫。

知識庫暫不支持文件刪除,該功能將在后續(xù)版本中推出。
"""

# 初始化消息
model_status = init_model()

default_theme_args = dict(
    font=["Source Sans Pro", 'ui-sans-serif', 'system-ui', 'sans-serif'],
    font_mono=['IBM Plex Mono', 'ui-monospace', 'Consolas', 'monospace'],
)

# Blocks API用于構(gòu)建交互式界面,創(chuàng)建一個名為demo的塊。該塊包含三個狀態(tài)變量:
# vs_path、file_status和model_status
with gr.Blocks(css=block_css, theme=gr.themes.Default(**default_theme_args)) as demo:
# gr.State是Gradio提供的一種不可見控件,用于存儲同一用戶運(yùn)行演示時的會話狀態(tài)。
# 當(dāng)用戶刷新頁面時,State變量的值被清除。它的目的是在后臺存儲一些變量方便訪問和交互。
    vs_path, file_status, model_status = gr.State(
        os.path.join(KB_ROOT_PATH, get_vs_list()[0], "vector_store") if len(get_vs_list()) > 1 else ""), gr.State(
        ""), gr.State(
        model_status)
    gr.Markdown(webui_title)
    # Tab用來控制功能切換的標(biāo)簽
    with gr.Tab("對話"):
        # gr.Row() 會創(chuàng)建一個水平方向的行,之后的組件默認(rèn)會按順序水平排列在這一行內(nèi)
        # 這里是將對話框和選擇框放在同一行,做了一個大對齊
        with gr.Row():
            # 這一列的寬度是默認(rèn)列寬的 10 倍
            with gr.Column(scale=10):
                # 最上面的框
                chatbot = gr.Chatbot([[None, init_message], [None, model_status.value]],
                                     elem_id="chat-box",
                                     show_label=False).style(height=750)
                # 最下面的輸入框,注意可通過調(diào)用.style()方法來設(shè)置組件的 CSS 樣式
                query = gr.Textbox(show_label=False,
                                   placeholder="請輸入提問內(nèi)容,按回車進(jìn)行提交").style(container=False)
            with gr.Column(scale=5):
                # Radio 組件實(shí)現(xiàn)了一個單選按鈕組,可以通過mode變量得到用戶的選擇
                mode = gr.Radio(["LLM 對話", "知識庫問答", "Bing搜索問答"],
                                label="請選擇使用模式",
                                value="知識庫問答", )
                # 使用 Grace 的 Accordion 組件創(chuàng)建了一個折疊面板
                # visible 屬性來顯示或隱藏這個面板
                knowledge_set = gr.Accordion("知識庫設(shè)定", visible=False)
                vs_setting = gr.Accordion("配置知識庫")
                # 為單選按鈕綁定 change 事件處理函數(shù) change_mode
                mode.change(fn=change_mode,
                            # change_mode函數(shù)的輸入輸出
                            inputs=[mode, chatbot],
                            outputs=[vs_setting, knowledge_set, chatbot])
                with vs_setting:
                    vs_refresh = gr.Button("更新已有知識庫選項(xiàng)")
                    # 下拉框
                    # interactive=True時,組件變?yōu)榻换タ捎脿顟B(tài),用戶可以修改或選擇
                    select_vs = gr.Dropdown(get_vs_list(),
                                            label="請選擇要加載的知識庫",
                                            interactive=True,
                                            value=get_vs_list()[0] if len(get_vs_list()) > 0 else None
                                            )
                    vs_name = gr.Textbox(label="請輸入新建知識庫名稱,當(dāng)前知識庫命名暫不支持中文",
                                         lines=1,
                                         interactive=True,
                                         visible=True)
                    vs_add = gr.Button(value="添加至知識庫選項(xiàng)", visible=True)
                    vs_delete = gr.Button("刪除本知識庫", visible=False)
                    file2vs = gr.Column(visible=False)
                    with file2vs:
                        # load_vs = gr.Button("加載知識庫")
                        gr.Markdown("向知識庫中添加文件")
                        sentence_size = gr.Number(value=SENTENCE_SIZE, precision=0,
                                                  label="文本入庫分句長度限制",
                                                  interactive=True, visible=True)
                        with gr.Tab("上傳文件"):
                            files = gr.File(label="添加文件",
                                            file_types=['.txt', '.md', '.docx', '.pdf', '.png', '.jpg', ".csv"],
                                            file_count="multiple",
                                            show_label=False)
                            load_file_button = gr.Button("上傳文件并加載知識庫")
                        with gr.Tab("上傳文件夾"):
                            folder_files = gr.File(label="添加文件",
                                                   file_count="directory",
                                                   show_label=False)
                            load_folder_button = gr.Button("上傳文件夾并加載知識庫")
                        with gr.Tab("刪除文件"):
                            files_to_delete = gr.CheckboxGroup(choices=[],
                                                               label="請從知識庫已有文件中選擇要刪除的文件",
                                                               interactive=True)
                            delete_file_button = gr.Button("從知識庫中刪除選中文件")
                    # 這里綁定了select_vs,后面還有一個test,因此綁定的refresh_vs_list函數(shù)要返回兩個值
                    # select_vs此時的值被改變了,因此觸發(fā)了change動作綁定的change_vs_name_input函數(shù)
                    vs_refresh.click(fn=refresh_vs_list,
                                     inputs=[],
                                     outputs=select_vs)
                    vs_add.click(fn=add_vs_name,
                                 inputs=[vs_name, chatbot],
                                 outputs=[select_vs, vs_name, vs_add, file2vs, chatbot, vs_delete])
                    vs_delete.click(fn=delete_vs,
                                    inputs=[select_vs, chatbot],
                                    outputs=[select_vs, vs_name, vs_add, file2vs, chatbot, vs_delete])
                    select_vs.change(fn=change_vs_name_input,
                                      inputs=[select_vs, chatbot],
                                      outputs=[vs_name, vs_add, file2vs, vs_path, chatbot, files_to_delete, vs_delete])
                    load_file_button.click(get_vector_store,
                                           show_progress=True,
                                           inputs=[select_vs, files, sentence_size, chatbot, vs_add, vs_add],
                                           outputs=[vs_path, files, chatbot, files_to_delete], )
                    load_folder_button.click(get_vector_store,
                                             show_progress=True,
                                             inputs=[select_vs, folder_files, sentence_size, chatbot, vs_add,
                                                     vs_add],
                                             outputs=[vs_path, folder_files, chatbot, files_to_delete], )
                    flag_csv_logger.setup([query, vs_path, chatbot, mode], "flagged")
                    query.submit(get_answer,
                                 [query, vs_path, chatbot, mode],
                                 [chatbot, query])
                    delete_file_button.click(delete_file,
                                             show_progress=True,
                                             inputs=[select_vs, files_to_delete, chatbot],
                                             outputs=[files_to_delete, chatbot])
    with gr.Tab("知識庫測試 Beta"):
        # gr.Row() 會創(chuàng)建一個水平方向的行,之后的組件默認(rèn)會按順序水平排列在這一行內(nèi)
        # 這里是將對話框和選擇框放在同一行,做了一個大對齊
        with gr.Row():
            # 這一列的寬度是默認(rèn)列寬的 10 倍
            with gr.Column(scale=10):
                # 最上面的框
                chatbot = gr.Chatbot([[None, knowledge_base_test_mode_info]],
                                     elem_id="chat-box",
                                     show_label=False).style(height=750)
                # 最下面的輸入框
                query = gr.Textbox(show_label=False,
                                   placeholder="請輸入提問內(nèi)容,按回車進(jìn)行提交").style(container=False)
            with gr.Column(scale=5):
                # Radio 組件實(shí)現(xiàn)了一個單選按鈕組,可以通過mode變量得到用戶的選擇,這里直接設(shè)不可見
                mode = gr.Radio(["知識庫測試"],  # "知識庫問答",
                                label="請選擇使用模式",
                                value="知識庫測試",
                                visible=False)
                # 使用 Grace 的 Accordion 組件創(chuàng)建了一個折疊面板
                knowledge_set = gr.Accordion("知識庫設(shè)定", visible=True)
                vs_setting = gr.Accordion("配置知識庫", visible=True)
                # 為單選按鈕綁定 change 事件處理函數(shù) change_mode
                mode.change(fn=change_mode,
                            inputs=[mode, chatbot],
                            outputs=[vs_setting, knowledge_set, chatbot])
                with knowledge_set:
                    # 數(shù)字輸入組件
                    score_threshold = gr.Number(value=VECTOR_SEARCH_SCORE_THRESHOLD,
                                                label="知識相關(guān)度 Score 閾值,分值越低匹配度越高",
                                                precision=0,
                                                interactive=True)
                    vector_search_top_k = gr.Number(value=VECTOR_SEARCH_TOP_K, precision=0,
                                                    label="獲取知識庫內(nèi)容條數(shù)", interactive=True)
                    chunk_conent = gr.Checkbox(value=False,
                                               label="是否啟用上下文關(guān)聯(lián)",
                                               interactive=True)
                    chunk_sizes = gr.Number(value=CHUNK_SIZE, precision=0,
                                            label="匹配單段內(nèi)容的連接上下文后最大長度",
                                            interactive=True, visible=False)
                    chunk_conent.change(fn=change_chunk_conent,
                                        inputs=[chunk_conent, gr.Textbox(value="chunk_conent", visible=False), chatbot],
                                        outputs=[chunk_sizes, chatbot])
                with vs_setting:
                    vs_refresh = gr.Button("更新已有知識庫選項(xiàng)")
                    # 不同Tab下標(biāo)志同一動作開始的刷新鍵可以共用一個名字,但是各Tab下動作影響的
                    # 組件需要起不同的名字,并且在函數(shù)返回時依次賦值給各個組件并更新
                    select_vs_test = gr.Dropdown(get_vs_list(),
                                                 label="請選擇要加載的知識庫",
                                                 interactive=True,
                                                 value=get_vs_list()[0] if len(get_vs_list()) > 0 else None)
                    vs_name = gr.Textbox(label="請輸入新建知識庫名稱,當(dāng)前知識庫命名暫不支持中文",
                                         lines=1,
                                         interactive=True,
                                         visible=True)
                    vs_add = gr.Button(value="添加至知識庫選項(xiàng)", visible=True)
                    file2vs = gr.Column(visible=False)
                    with file2vs:
                        # load_vs = gr.Button("加載知識庫")
                        gr.Markdown("向知識庫中添加單條內(nèi)容或文件")
                        sentence_size = gr.Number(value=SENTENCE_SIZE, precision=0,
                                                  label="文本入庫分句長度限制",
                                                  interactive=True, visible=True)
                        with gr.Tab("上傳文件"):
                            files = gr.File(label="添加文件",
                                            file_types=['.txt', '.md', '.docx', '.pdf'],
                                            file_count="multiple",
                                            show_label=False
                                            )
                            load_file_button = gr.Button("上傳文件并加載知識庫")
                        with gr.Tab("上傳文件夾"):
                            folder_files = gr.File(label="添加文件",
                                                   # file_types=['.txt', '.md', '.docx', '.pdf'],
                                                   file_count="directory",
                                                   show_label=False)
                            load_folder_button = gr.Button("上傳文件夾并加載知識庫")
                        with gr.Tab("添加單條內(nèi)容"):
                            one_title = gr.Textbox(label="標(biāo)題", placeholder="請輸入要添加單條段落的標(biāo)題", lines=1)
                            one_conent = gr.Textbox(label="內(nèi)容", placeholder="請輸入要添加單條段落的內(nèi)容", lines=5)
                            one_content_segmentation = gr.Checkbox(value=True, label="禁止內(nèi)容分句入庫",
                                                                   interactive=True)
                            load_conent_button = gr.Button("添加內(nèi)容并加載知識庫")
                    # 將上傳的文件保存到content文件夾下,并更新下拉框,注意這里是select_vs_test
                    vs_refresh.click(fn=refresh_vs_list,
                                     inputs=[],
                                     outputs=select_vs_test)
                    vs_add.click(fn=add_vs_name,
                                 inputs=[vs_name, chatbot],
                                 outputs=[select_vs_test, vs_name, vs_add, file2vs, chatbot])
                    select_vs_test.change(fn=change_vs_name_input,
                                          inputs=[select_vs_test, chatbot],
                                          outputs=[vs_name, vs_add, file2vs, vs_path, chatbot])
                    load_file_button.click(get_vector_store,
                                           show_progress=True,
                                           inputs=[select_vs_test, files, sentence_size, chatbot, vs_add, vs_add],
                                           outputs=[vs_path, files, chatbot], )
                    load_folder_button.click(get_vector_store,
                                             show_progress=True,
                                             inputs=[select_vs_test, folder_files, sentence_size, chatbot, vs_add,
                                                     vs_add],
                                             outputs=[vs_path, folder_files, chatbot], )
                    load_conent_button.click(get_vector_store,
                                             show_progress=True,
                                             inputs=[select_vs_test, one_title, sentence_size, chatbot,
                                                     one_conent, one_content_segmentation],
                                             outputs=[vs_path, files, chatbot], )
                    flag_csv_logger.setup([query, vs_path, chatbot, mode], "flagged")
                    query.submit(get_answer,
                                 [query, vs_path, chatbot, mode, score_threshold, vector_search_top_k, chunk_conent,
                                  chunk_sizes],
                                 [chatbot, query])
    with gr.Tab("模型配置"):
        llm_model = gr.Radio(llm_model_dict_list,
                             label="LLM 模型",
                             value=LLM_MODEL,
                             interactive=True)
        no_remote_model = gr.Checkbox(shared.LoaderCheckPoint.no_remote_model,
                                      label="加載本地模型",
                                      interactive=True)
        llm_history_len = gr.Slider(0, 10,
                                    value=LLM_HISTORY_LEN,
                                    step=1,
                                    label="LLM 對話輪數(shù)",
                                    interactive=True)
        use_ptuning_v2 = gr.Checkbox(USE_PTUNING_V2,
                                     label="使用p-tuning-v2微調(diào)過的模型",
                                     interactive=True)
        use_lora = gr.Checkbox(USE_LORA,
                               label="使用lora微調(diào)的權(quán)重",
                               interactive=True)
        embedding_model = gr.Radio(embedding_model_dict_list,
                                   label="Embedding 模型",
                                   value=EMBEDDING_MODEL,
                                   interactive=True)
        top_k = gr.Slider(1, 20, value=VECTOR_SEARCH_TOP_K, step=1,
                          label="向量匹配 top k", interactive=True)
        load_model_button = gr.Button("重新加載模型")
        load_model_button.click(reinit_model, show_progress=True,
                                inputs=[llm_model, embedding_model, llm_history_len, no_remote_model, use_ptuning_v2,
                                        use_lora, top_k, chatbot], outputs=chatbot)
        # load_knowlege_button = gr.Button("重新構(gòu)建知識庫")
        # load_knowlege_button.click(reinit_vector_store, show_progress=True,
        #                            inputs=[select_vs, chatbot], outputs=chatbot)
    demo.load(
        # 加載初始化邏輯refresh_vs_list,并傳入輸出組件
        fn=refresh_vs_list,
        inputs=None,
        outputs=[select_vs, select_vs_test],
        # 加入后臺執(zhí)行隊(duì)列
        queue=True,
        show_progress=False,
    )

(demo
    # 限制回調(diào)函數(shù)的最多并發(fā)執(zhí)行數(shù)為3以避免應(yīng)用過載
 .queue(concurrency_count=3)
 .launch(server_name='172.20.63.134',
         server_port=7860,
         show_api=False,
         share=False,
         inbrowser=False))

回調(diào)函數(shù)具體實(shí)現(xiàn)

監(jiān)聽到前端的事件后調(diào)用的回調(diào)函數(shù),負(fù)責(zé)實(shí)現(xiàn)前后端交互。需要注意的一點(diǎn)是,chatbot中顯示新的聊天內(nèi)容并不是在原來的基礎(chǔ)上添加,而是從頭到尾的重新打印,所以基本上每個函數(shù)都要傳舊的history和返回新的history。文章來源地址http://www.zghlxwxcb.cn/news/detail-622911.html

獲取知識庫列表

def get_vs_list():
    # 返回當(dāng)前最新的經(jīng)排序后的知識庫列表
    lst_default = ["新建知識庫"]
    if not os.path.exists(KB_ROOT_PATH):
        return lst_default
    lst = os.listdir(KB_ROOT_PATH)
    if not lst:
        return lst_default
    lst.sort()
    return lst_default + lst

獲取不同模式下的回答

  • query.submit動作綁定的函數(shù)
def get_answer(query, vs_path, history, mode, score_threshold=VECTOR_SEARCH_SCORE_THRESHOLD,
               vector_search_top_k=VECTOR_SEARCH_TOP_K, chunk_conent: bool = True,
               chunk_size=CHUNK_SIZE, streaming: bool = STREAMING):
    if mode == "Bing搜索問答":
        for resp, history in local_doc_qa.get_search_result_based_answer(
                query=query, chat_history=history, streaming=streaming):
            source = "\n\n"
            source += "".join(
                [
                    f"""<details> <summary>出處 [{i + 1}] <a href="{doc.metadata["source"]}" target="_blank">{doc.metadata["source"]}</a> </summary>\n"""
                    f"""{doc.page_content}\n"""
                    f"""</details>"""
                    for i, doc in
                    enumerate(resp["source_documents"])])
            history[-1][-1] += source
            yield history, ""
    # "index.faiss"是向量索引的文件名,可以根據(jù)文件存在性,來判斷向量索引是否需要構(gòu)建。
    elif mode == "知識庫問答" and vs_path is not None and os.path.exists(vs_path) and "index.faiss" in os.listdir(
            vs_path):
        # 注意score_threshold, vector_search_top_k, chunk_conent,chunk_size
        # 這幾個參數(shù)壓根沒傳進(jìn)get_knowledge_based_answer
        for resp, history in local_doc_qa.get_knowledge_based_answer(
                query=query, vs_path=vs_path, chat_history=history, streaming=streaming):
            source = "\n\n"
            source += "".join(
                [f"""<details> <summary>出處 [{i + 1}] {os.path.split(doc.metadata["source"])[-1]}</summary>\n"""
                 f"""{doc.page_content}\n"""
                 f"""</details>"""
                 for i, doc in
                 enumerate(resp["source_documents"])])
            history[-1][-1] += source
            # 分別賦值給chatbot和query
            yield history, ""
    elif mode == "知識庫測試":
        if os.path.exists(vs_path):
            # 使用了全部傳入?yún)?shù),但是只是用于測試文件匹配度不能回答
            resp, prompt = local_doc_qa.get_knowledge_based_conent_test(query=query, vs_path=vs_path,
                                                                        score_threshold=score_threshold,
                                                                        vector_search_top_k=vector_search_top_k,
                                                                        chunk_conent=chunk_conent,
                                                                        chunk_size=chunk_size)
            if not resp["source_documents"]:
                yield history + [[query,
                                  "根據(jù)您的設(shè)定,沒有匹配到任何內(nèi)容,請確認(rèn)您設(shè)置的知識相關(guān)度 Score 閾值是否過小或其他參數(shù)是否正確。"]], ""
            else:
                source = "\n".join(
                    [
                        f"""<details open> <summary>【知識相關(guān)度 Score】:{doc.metadata["score"]} - 【出處{i + 1}】:  {os.path.split(doc.metadata["source"])[-1]} </summary>\n"""
                        f"""{doc.page_content}\n"""
                        f"""</details>"""
                        for i, doc in
                        enumerate(resp["source_documents"])])
                history.append([query, "以下內(nèi)容為知識庫中滿足設(shè)置條件的匹配結(jié)果:\n\n" + source])
                yield history, ""
        else:
            yield history + [[query,
                              "請選擇知識庫后進(jìn)行測試,當(dāng)前未選擇知識庫。"]], ""
    else:

        answer_result_stream_result = local_doc_qa.llm_model_chain(
            {"prompt": query, "history": history, "streaming": streaming})

        for answer_result in answer_result_stream_result['answer_result_stream']:
            resp = answer_result.llm_output["answer"]
            history = answer_result.history
            history[-1][-1] = resp
            yield history, ""
    logger.info(f"flagging: username={FLAG_USER_NAME},query={query},vs_path={vs_path},mode={mode},history={history}")
    flag_csv_logger.flag([query, vs_path, history, mode], username=FLAG_USER_NAME)

模型初始化

  • 初始化model_status
def init_model():
    args = parser.parse_args()

    args_dict = vars(args)
    shared.loaderCheckPoint = LoaderCheckPoint(args_dict)
    llm_model_ins = shared.loaderLLM()
    llm_model_ins.history_len = LLM_HISTORY_LEN
    try:
        local_doc_qa.init_cfg(llm_model=llm_model_ins)
        answer_result_stream_result = local_doc_qa.llm_model_chain(
            {"prompt": "你好", "history": [], "streaming": False})

        for answer_result in answer_result_stream_result['answer_result_stream']:
            print(answer_result.llm_output)
        reply = """模型已成功加載,可以開始對話,或從右側(cè)選擇模式后開始對話"""
        logger.info(reply)
        return reply
    except Exception as e:
        logger.error(e)
        reply = """模型未成功加載,請到頁面左上角"模型配置"選項(xiàng)卡中重新選擇后點(diǎn)擊"加載模型"按鈕"""
        if str(e) == "Unknown platform: darwin":
            logger.info("該報(bào)錯可能因?yàn)槟褂玫氖?macOS 操作系統(tǒng),需先下載模型至本地后執(zhí)行 Web UI,具體方法請參考項(xiàng)目 README 中本地部署方法及常見問題:"
                        " https://github.com/imClumsyPanda/langchain-ChatGLM")
        else:
            logger.info(reply)
        return reply

模型重加載

  • load_model_button.click動作綁定的函數(shù)
def reinit_model(llm_model, embedding_model, llm_history_len, no_remote_model, use_ptuning_v2, use_lora, top_k,
                 history):
    try:
        llm_model_ins = shared.loaderLLM(llm_model, no_remote_model, use_ptuning_v2)
        llm_model_ins.history_len = llm_history_len
        local_doc_qa.init_cfg(llm_model=llm_model_ins,
                              embedding_model=embedding_model,
                              top_k=top_k)
        model_status = """模型已成功重新加載,可以開始對話,或從右側(cè)選擇模式后開始對話"""
        logger.info(model_status)
    except Exception as e:
        logger.error(e)
        model_status = """模型未成功重新加載,請到頁面左上角"模型配置"選項(xiàng)卡中重新選擇后點(diǎn)擊"加載模型"按鈕"""
        logger.info(model_status)
    # 更新chatbot的值
    return history + [[None, model_status]]

文件向量化

  • load_file_button.click和load_folder_button.click動作綁定的函數(shù)
def get_vector_store(vs_id, files, sentence_size, history, one_conent, one_content_segmentation):
    vs_path = os.path.join(KB_ROOT_PATH, vs_id, "vector_store")
    filelist = []
    if local_doc_qa.llm_model_chain and local_doc_qa.embeddings:
        if isinstance(files, list):
            for file in files:
                filename = os.path.split(file.name)[-1]
                shutil.move(file.name, os.path.join(KB_ROOT_PATH, vs_id, "content", filename))
                filelist.append(os.path.join(KB_ROOT_PATH, vs_id, "content", filename))
            vs_path, loaded_files = local_doc_qa.init_knowledge_vector_store(filelist, vs_path, sentence_size)
        else:
            vs_path, loaded_files = local_doc_qa.one_knowledge_add(vs_path, files, one_conent, one_content_segmentation,
                                                                   sentence_size)
        if len(loaded_files):
            file_status = f"已添加 {'、'.join([os.path.split(i)[-1] for i in loaded_files if i])} 內(nèi)容至知識庫,并已加載知識庫,請開始提問"
        else:
            file_status = "文件未成功加載,請重新上傳文件"
    else:
        file_status = "模型未完成加載,請先在加載模型后再導(dǎo)入文件"
        vs_path = None
    logger.info(file_status)
    return vs_path, None, history + [[None, file_status]], \
           gr.update(choices=local_doc_qa.list_file_from_vector_store(vs_path) if vs_path else [])

選擇知識庫

  • select_vs.change和select_vs_test.change動作所綁定的函數(shù),如果刷新知識庫會有bug
def change_vs_name_input(vs_id, history):
    if vs_id == "新建知識庫":
        return gr.update(visible=True), gr.update(visible=True), gr.update(visible=False), None, history, \
               gr.update(choices=[]), gr.update(visible=False)
    else:
        # 刷新時這地方有bug,直接傳了個列表過去,逆天
        vs_path = os.path.join(KB_ROOT_PATH, vs_id, "vector_store")
        if "index.faiss" in os.listdir(vs_path):
            file_status = f"已加載知識庫{vs_id},請開始提問"
            return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), \
                   vs_path, history + [[None, file_status]], \
                   gr.update(choices=local_doc_qa.list_file_from_vector_store(vs_path), value=[]), \
                   gr.update(visible=True)
        else:
            file_status = f"已選擇知識庫{vs_id},當(dāng)前知識庫中未上傳文件,請先上傳文件后,再開始提問"
            return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), \
                   vs_path, history + [[None, file_status]], \
                   gr.update(choices=[], value=[]), gr.update(visible=True, value=[])


knowledge_base_test_mode_info = ("【注意】\n\n"
                                 "1. 您已進(jìn)入知識庫測試模式,您輸入的任何對話內(nèi)容都將用于進(jìn)行知識庫查詢,"
                                 "并僅輸出知識庫匹配出的內(nèi)容及相似度分值和及輸入的文本源路徑,查詢的內(nèi)容并不會進(jìn)入模型查詢。\n\n"
                                 "2. 知識相關(guān)度 Score 經(jīng)測試,建議設(shè)置為 500 或更低,具體設(shè)置情況請結(jié)合實(shí)際使用調(diào)整。"
                                 """3. 使用"添加單條數(shù)據(jù)"添加文本至知識庫時,內(nèi)容如未分段,則內(nèi)容越多越會稀釋各查詢內(nèi)容與之關(guān)聯(lián)的score閾值。\n\n"""
                                 "4. 單條內(nèi)容長度建議設(shè)置在100-150左右。\n\n"
                                 "5. 本界面用于知識入庫及知識匹配相關(guān)參數(shù)設(shè)定,但當(dāng)前版本中,"
                                 "本界面中修改的參數(shù)并不會直接修改對話界面中參數(shù),仍需前往`configs/model_config.py`修改后生效。"
                                 "相關(guān)參數(shù)將在后續(xù)版本中支持本界面直接修改。")

切換模型

  • mode.change動作綁定的函數(shù)
def change_mode(mode, history):
    # 調(diào)整vs_setting, knowledge_set, chatbot的可見性
    if mode == "知識庫問答":
        return gr.update(visible=True), gr.update(visible=False), history
        # + [[None, "【注意】:您已進(jìn)入知識庫問答模式,您輸入的任何查詢都將進(jìn)行知識庫查詢,然后會自動整理知識庫關(guān)聯(lián)內(nèi)容進(jìn)入模型查詢?。?!"]]
    elif mode == "知識庫測試":
        return gr.update(visible=True), gr.update(visible=True), [[None,
                                                                   knowledge_base_test_mode_info]]
    else:
        return gr.update(visible=False), gr.update(visible=False), history

啟用上下文

  • chunk_conent.change動作綁定的函數(shù)
def change_chunk_conent(mode, label_conent, history):
    # 更新chunk_sizes, chatbot
    conent = ""
    if "chunk_conent" in label_conent:
        conent = "搜索結(jié)果上下文關(guān)聯(lián)"
    elif "one_content_segmentation" in label_conent:  # 這里沒用上,可以先留著
        conent = "內(nèi)容分段入庫"

    if mode:
        return gr.update(visible=True), history + [[None, f"【已開啟{conent}】"]]
    else:
        return gr.update(visible=False), history + [[None, f"【已關(guān)閉{conent}】"]]

創(chuàng)建新的知識庫

  • vs_add.click動作所綁定的函數(shù)
def add_vs_name(vs_name, chatbot):
    if vs_name is None or vs_name.strip() == "":
        vs_status = "知識庫名稱不能為空,請重新填寫知識庫名稱"
        chatbot = chatbot + [[None, vs_status]]
        return gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), gr.update(
            visible=False), chatbot, gr.update(visible=False)
    elif vs_name in get_vs_list():
        vs_status = "與已有知識庫名稱沖突,請重新選擇其他名稱后提交"
        chatbot = chatbot + [[None, vs_status]]
        return gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), gr.update(
            visible=False), chatbot, gr.update(visible=False)
    else:
        # 新建上傳文件存儲路徑
        if not os.path.exists(os.path.join(KB_ROOT_PATH, vs_name, "content")):
            os.makedirs(os.path.join(KB_ROOT_PATH, vs_name, "content"))
        # 新建向量庫存儲路徑
        if not os.path.exists(os.path.join(KB_ROOT_PATH, vs_name, "vector_store")):
            os.makedirs(os.path.join(KB_ROOT_PATH, vs_name, "vector_store"))
        vs_status = f"""已新增知識庫"{vs_name}",將在上傳文件并載入成功后進(jìn)行存儲。請?jiān)陂_始對話前,先完成文件上傳。 """
        chatbot = chatbot + [[None, vs_status]]
        # 更新select_vs, vs_name, vs_add, file2vs, chatbot, vs_delete這幾個組件
        return gr.update(visible=True, choices=get_vs_list(), value=vs_name), gr.update(
            visible=False), gr.update(visible=False), gr.update(visible=True), chatbot, gr.update(visible=True)

更新知識庫

  • vs_refresh.click和demo.load動作綁定的事件
def refresh_vs_list():
	# 更新select_vs, select_vs_test兩個組件
    return gr.update(choices=get_vs_list()), gr.update(choices=get_vs_list())

刪除文件及整個知識庫

def delete_file(vs_id, files_to_delete, chatbot):
    vs_path = os.path.join(KB_ROOT_PATH, vs_id, "vector_store")
    content_path = os.path.join(KB_ROOT_PATH, vs_id, "content")
    docs_path = [os.path.join(content_path, file) for file in files_to_delete]
    status = local_doc_qa.delete_file_from_vector_store(vs_path=vs_path,
                                                        filepath=docs_path)
    if "fail" not in status:
        for doc_path in docs_path:
            if os.path.exists(doc_path):
                os.remove(doc_path)
    rested_files = local_doc_qa.list_file_from_vector_store(vs_path)
    if "fail" in status:
        vs_status = "文件刪除失敗。"
    elif len(rested_files) > 0:
        vs_status = "文件刪除成功。"
    else:
        vs_status = f"文件刪除成功,知識庫{vs_id}中無已上傳文件,請先上傳文件后,再開始提問。"
    logger.info(",".join(files_to_delete) + vs_status)
    chatbot = chatbot + [[None, vs_status]]
    return gr.update(choices=local_doc_qa.list_file_from_vector_store(vs_path), value=[]), chatbot


def delete_vs(vs_id, chatbot):
    try:
        shutil.rmtree(os.path.join(KB_ROOT_PATH, vs_id))
        status = f"成功刪除知識庫{vs_id}"
        logger.info(status)
        chatbot = chatbot + [[None, status]]
        return gr.update(choices=get_vs_list(), value=get_vs_list()[0]), gr.update(visible=True), gr.update(
            visible=True), \
               gr.update(visible=False), chatbot, gr.update(visible=False)
    except Exception as e:
        logger.error(e)
        status = f"刪除知識庫{vs_id}失敗"
        chatbot = chatbot + [[None, status]]
        return gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), \
               gr.update(visible=True), chatbot, gr.update(visible=True)

到了這里,關(guān)于langchain-ChatGLM源碼閱讀:webui.py的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Langchain-ChatGLM配置文件參數(shù)測試

    Langchain-ChatGLM配置文件參數(shù)測試

    1 已知可能影響對話效果的參數(shù)(位于configs/model_config.py文件): 其中可能對讀取知識庫影響較大的變量有CHUNK_SIZE(單段參考上下文的長度),VECTOR_SEARCH_TOP_K(知識庫參考文段數(shù)量),和VECTOR_SEARCH_SCORE_THRESHOLD(知識庫匹配內(nèi)容需要達(dá)到的最小相關(guān)度)。本實(shí)驗(yàn)將通過向不同

    2024年02月16日
    瀏覽(21)
  • LangChain-ChatGLM在WIndows10下的部署

    LangChain-ChatGLM在WIndows10下的部署

    1、LangChain + ChatGLM2-6B 搭建個人專屬知識庫中的LangChain + ChatGLM2-6B 構(gòu)建知識庫這一節(jié):基本的邏輯和步驟是對的,但要根據(jù)Windows和現(xiàn)狀做很多調(diào)整。 2、沒有動過model_config.py中的“LORA_MODEL_PATH_BAICHUAN”這一項(xiàng)內(nèi)容,卻報(bào)錯:對報(bào)錯“LORA_MODEL_PATH_BAICHUAN”提供了重要解決思路,雖

    2024年02月13日
    瀏覽(21)
  • windows環(huán)境下的langchain-ChatGLM的本地部署

    windows環(huán)境下的langchain-ChatGLM的本地部署

    首先是項(xiàng)目開源地址?https://github.com/imClumsyPanda/langchain-ChatGLM 下載這個項(xiàng)目的源碼非常簡單,但運(yùn)行起來十分麻煩,各種環(huán)境的搭配簡直是折磨人,尤其是電腦上缺少各種安裝環(huán)境的,我首先先列舉幾個,例如conda安裝python的虛擬環(huán)境,用這個比較方便,還有Anoconda的安裝,

    2024年02月13日
    瀏覽(29)
  • 2M大小的PDF文檔上傳到LangChain-ChatGLM知識圖譜中,大致需要的時間

    對于將2M大小的PDF文檔上傳到LangChain-ChatGLM知識圖譜中,大致需要的時間如下: PDF到文本的提取轉(zhuǎn)換:若PDF內(nèi)容主要為文本,此步驟約需要1-2分鐘。 提取的文本經(jīng)過預(yù)處理與分析:此步驟需要對文本進(jìn)行分詞、命名實(shí)體識別等處理,約需要2-5分鐘。 抽取文本中的結(jié)構(gòu)化知識(實(shí)體、關(guān)

    2024年02月08日
    瀏覽(20)
  • CentOS7上部署langchain-chatglm或stable-diffusion可能遇到的Bug的解決方案

    CentOS7上部署langchain-chatglm或stable-diffusion可能遇到的Bug的解決方案

    進(jìn)入你的代碼目錄下 下載依賴 這里可能有的朋友會有問題會出現(xiàn)某些包下載不了,這里建議直接使用阿里源即可,在確定你的cuda版本之后(使用nvidia-smi確定cuda版本) 命令行執(zhí)行 卸載掉剛才pip安裝的版本!!!!因?yàn)榇颂幇惭b的版本還缺少cuda的支持,確定卸載掉之后 執(zhí)行 此處X為

    2024年02月16日
    瀏覽(32)
  • 探索LangChain-ChatGLM-Webui:下一代多語言聊天機(jī)器人平臺

    項(xiàng)目地址:https://gitcode.com/thomas-yanxin/LangChain-ChatGLM-Webui LangChain-ChatGLM-Webui 是一個基于開源自然語言處理庫 Hugging Face Transformers 和 OpenAI\\\'s GPT-3 的多語言聊天機(jī)器人平臺。它允許用戶通過Web界面與強(qiáng)大的自然語言模型進(jìn)行交互,實(shí)現(xiàn)跨語言、跨文化的智能對話體驗(yàn)。 1. 基于Trans

    2024年04月15日
    瀏覽(30)
  • LLMs之RAG:LangChain-ChatGLM-Webui(一款基于本地知識庫(各種文本文檔)的自動問答的GUI界面實(shí)現(xiàn))的簡介、安裝、使用方法之詳細(xì)攻略

    LLMs之RAG:LangChain-ChatGLM-Webui(一款基于本地知識庫(各種文本文檔)的自動問答的GUI界面實(shí)現(xiàn))的簡介、安裝、使用方法之詳細(xì)攻略 目錄 LangChain-ChatGLM-Webui的簡介 1、支持的模型 LangChain-ChatGLM-Webui的安裝 1、安裝 T1、直接安裝? 環(huán)境準(zhǔn)備 啟動程序 T2、Docker安裝 (1)、Docker 基礎(chǔ)環(huán)境運(yùn)

    2024年02月04日
    瀏覽(16)
  • langchain源碼閱讀系列(三)之Chain模塊

    langchain源碼閱讀系列(三)之Chain模塊

    原文首發(fā)于博客文章langchain源碼閱讀 本節(jié)是langchian源碼閱讀系列第三篇,下面進(jìn)入Chain模塊??: LLM 應(yīng)用構(gòu)建實(shí)踐筆記 Chain鏈定義 鏈定義為對組件的一系列調(diào)用,也可以包括其他鏈,這種在鏈中將組件組合在一起的想法很簡單但功能強(qiáng)大,極大地簡化了復(fù)雜應(yīng)用程序的實(shí)現(xiàn)并

    2024年02月13日
    瀏覽(22)
  • langchain源碼閱讀系列(五)之Callback模塊

    langchain源碼閱讀系列(五)之Callback模塊

    原文首發(fā)于博客文章,詳情請前往博客langchain源碼閱讀 本節(jié)是langchian源碼閱讀系列第五篇,下面進(jìn)入Callback模塊??: LLM 應(yīng)用構(gòu)建實(shí)踐筆記 回調(diào)模塊允許接到LLM應(yīng)用程序的各個階段,鑒于LLM的幻覺問題,這對于日志記錄、監(jiān)視、流式處理和其他任務(wù)非常有用,現(xiàn)在也有專用的

    2024年02月13日
    瀏覽(18)
  • 阿里云部署 ChatGLM2-6B 與 langchain+ChatGLM

    阿里云部署 ChatGLM2-6B 與 langchain+ChatGLM

    更新系統(tǒng) 安裝git 克隆 ChatGLM2-6B 源碼 克隆 chatglm2-6b 模型 安裝 ChatGLM2-6B 依賴 修改模型的路徑 修改成 啟動服務(wù) 啟動成功后 克隆 langchain-ChatGLM 源碼 git clone https://github.com/imClumsyPanda/langchain-ChatGLM.git 克隆模型 安裝 langchain-ChatGLM 依賴 修改配置 修改一 修改成 修改二 修改成 修改

    2024年02月15日
    瀏覽(34)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包