[LLM] Uso de Langchain [3] (pregunta y respuesta basadas en documentos)

1. Preguntas y respuestas basadas en documentos

1. Crea una tienda de vectores

  • CSVLoader carga datos csv y el cargador se usa junto con el modelo
  • Utilice el almacenamiento de vector de búsqueda de memoria Dock Array, como un almacenamiento de vector de memoria, sin necesidad de conectarse a una base de datos externa
  • Cree una tienda de vectores: importe un índice, el creador de índices de la tienda de vectores
from langchain.chains import RetrievalQA #检索QA链,在文档上进行检索
from langchain.chat_models import ChatOpenAI #openai模型
from langchain.document_loaders import CSVLoader #文档加载器,采用csv格式存储
from langchain.vectorstores import DocArrayInMemorySearch #向量存储
from IPython.display import display, Markdown #在jupyter显示信息的工具

file = 'OutdoorClothingCatalog_1000.csv'
loader = CSVLoader(file_path=file)
#查看数据
import pandas as pd
data = pd.read_csv(file,header=None)

Los datos son datos de texto con campos como namey :description
inserte la descripción de la imagen aquí

# 创建向量存储
from langchain.indexes import VectorstoreIndexCreator #导入向量存储索引创建器
'''
将指定向量存储类,创建完成后,我们将从加载器中调用,通过文档记载器列表加载
'''
index = VectorstoreIndexCreator(
    vectorstore_cls=DocArrayInMemorySearch
).from_loaders([loader])
query ="Please list all your shirts with sun protection \
in a table in markdown and summarize each one."
response = index.query(query)#使用索引查询创建一个响应,并传入这个查询
display(Markdown(response))#查看查询返回的内容

inserte la descripción de la imagen aquí
Obtuve una tabla de Markdown con los nombres y descripciones de todas las camisas con protección solar, las descripciones están resumidas.

'''
为刚才的文本创建embedding,准备将它们存储在向量存储中,使用向量存储上的from documents方法来实现。
该方法接受文档列表、嵌入对象,然后我们将创建一个总体向量存储
'''
db = DocArrayInMemorySearch.from_documents(
    docs, 
    embeddings
)
query = "Please suggest a shirt with sunblocking"
docs = db.similarity_search(query)#使用这个向量存储来查找与传入查询类似的文本,如果我们在向量存储中使用相似性搜索方法并传入一个查询,我们将得到一个文档列表
len(docs)# 我们可以看到它返回了四个文档

# 回答文档的相关问题
retriever = db.as_retriever() #创建检索器通用接口
llm = ChatOpenAI(temperature = 0.0,max_tokens=1024) #导入语言模型
qdocs = "".join([docs[i].page_content for i in range(len(docs))])  # 将合并文档中的所有页面内容到一个变量中
response = llm.call_as_llm(f"{
    
    qdocs} Question: Please list all your \
shirts with sun protection in a table in markdown and summarize each one.") #列出所有具有防晒功能的衬衫并在Markdown表格中总结每个衬衫的语言模型

La base de datos vectorial utilizada es chromadb. Encapsulado por la cadena LangChain, cree una cadena de control de calidad de recuperación para responder preguntas sobre los documentos recuperados. Para crear dicha cadena, pasaremos algunas cosas diferentes

  • 1. Modelo de lenguaje, generación de texto al final.
  • 2. El tipo de cadena entrante, utilizado aquí stuff, introduce todos los documentos en el contexto y realiza una llamada al modelo de lenguaje.
  • 3. Pase en un perro perdiguero
qa_stuff = RetrievalQA.from_chain_type(
    llm=llm, 
    chain_type="stuff", 
    retriever=retriever, 
    verbose=True
)
query =  "Please list all your shirts with sun protection in a table \
in markdown and summarize each one."#创建一个查询并在此查询上运行链
response = qa_stuff.run(query)
display(Markdown(response))#使用 display 和 markdown 显示它

RetrievalQALa cadena en realidad encapsula los dos pasos de fusionar fragmentos de texto y llamar al modelo de lenguaje. Si no hay una cadena RetrievalQA, debemos implementarla de esta manera:

# 将检索出来的文本片段合并成一段文本
qdocs = "".join([docs[i].page_content for i in range(len(docs))])
# 将合并后的文本和问题一起传给LLM
response = llm.call_as_llm(f"{
    
    qdocs} Question: Please list all your \
shirts with sun protection in a table in markdown and summarize each one.") 

2. Diferentes tipos de cadenas

¿Qué sucede si desea realizar el mismo tipo de respuesta a preguntas en muchos tipos diferentes de bloques? El experimento anterior solo devolvió 4 documentos, si hay varios documentos, podemos usar algunos métodos diferentes

  • Map Reduce
    pasa todos los fragmentos al modelo de lenguaje junto con la pregunta, obtiene las respuestas, usa otra llamada de modelo de lenguaje para resumir todas las respuestas individuales en una respuesta final y puede operar en cualquier cantidad de documentos. Un solo problema se puede procesar en paralelo, lo que también requiere más llamadas. Trata todos los documentos como independientes.
  • Refine
    se usa para recorrer muchos documentos, de hecho de forma iterativa, basándose en respuestas de documentos anteriores, excelente para información causal hacia adelante y hacia atrás y construyendo respuestas progresivamente a lo largo del tiempo, según los resultados de llamadas anteriores. Por lo general, lleva más tiempo y básicamente requiere tantas llamadas como Map Reduce
  • Map Re-rank
    realiza una única llamada de modelo de idioma por documento, le pide que devuelva un puntaje, elige el puntaje más alto, esto se basa en que el modelo de lenguaje sabe cuál debe ser el puntaje, necesita decirlo, si es relevante para el documento, debe ser la puntuación más alta y las instrucciones de ajuste allí, se pueden procesar en lotes relativamente rápido, pero más caro
  • Stuff
    combina todo en un solo documento

2. Preguntas y respuestas de la base de conocimiento local

1.1 Marco general

inserte la descripción de la imagen aquí

  • Puntos mejorados (direcciones):
    • Cambiar modelo LLM
    • modelo de incrustación
    • método de segmentación de texto
    • Implementación de modelo acelerado de varias tarjetas
    • Mejora de la calidad de recuperación de recuperación top-k
  • Basado en la implementación de privacidad y privatización de datos, es conveniente usar el modelo grande Langchain+ para razonar

2. Segmentación de texto

Código fuente de Langchain: https://github.com/hwchase17/langchain/blob/master/langchain/text_splitter.py

Parámetros comunes del módulo de división de texto incorporado de Langchain:

  • chunk_size: el tamaño del bloque de texto, es decir, el tamaño máximo del bloque de texto;
  • chunk_overlap: indica el grado de superposición entre dos textos segmentados, la cantidad máxima de superposición entre bloques de texto, retener algo de superposición puede mantener la continuidad entre bloques de texto y se puede construir utilizando una ventana deslizante, que es más importante.
  • length_function: el método utilizado para calcular la longitud del bloque de texto, el valor predeterminado es simplemente calcular la cantidad de caracteres;

Otros separadores de texto:
 Text Splitter LatexTextSplitter divide el texto en títulos Latex, títulos, enumeraciones, etc. MarkdownTextSplitter divide el texto en encabezados Markdown, bloques de código o reglas horizontales. NLTKTextSplitter utiliza el divisor PythonCodeTextSplitter de NLTK para dividir el texto a lo largo de las definiciones de clases y métodos de Python. RecursiveCharacterTextSplitter Un separador de texto genérico. Toma como argumento una lista de caracteres e intenta convertir todos los párrafos (luego oraciones, Luego, las palabras) juntan SpacyTextSplitter Use el divisor TokenTextSplitter de Spacy para dividir según el número de token de openAl \begin{array}{|c|c|} \hline \text { text splitter} & \\ \hline \text { LatexTextSplitter } & \text { Divide el texto en encabezados, títulos, enumeraciones, etc. de Latex. } \\ \hline \text { MarkdownTextSplitter } & \begin{array}{l} \text { Dividir a lo largo de encabezados Markdown, bloques de código o reglas horizontales} \\ \text { Dividir texto. } \end{array} \\ \hline \text { NLTKTextSplitter } & \text { Use el divisor de NLTK} \\ \hline \text { PythonCodeTextSplitter } & \text { Divide el texto a lo largo de las definiciones de clases y métodos de Python. } \\ \hline \text { RecursiveCharacterTextSplitter } & \begin{array}{l} \text { Splitter para texto genérico. Toma una lista de caracteres como } \\ \text { argumento, pone todos los párrafos (luego oraciones, } \\ \text { luego palabras) juntos tanto como sea posible} \end{array} \\ \hline \ text { SpacyTextSplitter } & \text { Usar el divisor de Spacy} \\ \hline \text { TokenTextSplitter } & \text { Dividir según el número de token de openAl} \\ \hline \end{array} divisor de texto  LátexTextoDivisor  MarkdownTextSplitter  Divisor de texto NLTK  PythonCodeTextSplitter  RecursivoCaracterTextSplitter  SpacyTextSplitter TokenTextSplitter  Divida el texto a lo largo de encabezados, encabezados, enumeraciones, etc. de Latex .  Dividir a lo largo de encabezados de Markdown , bloques de código o reglas horizontales  cortar texto.   Divisor usando NLTK  Divida el texto a lo largo de las definiciones de métodos y clases de Python .  Un divisor para texto genérico. Toma una lista de caracteres como  parámetros trate de poner todos los párrafos  ( luego las oraciones  luego palabras   juntas Usando el divisor de Spacy   Dividir según el número de token de openAl
Tomemos una castaña directamente, como segmentar texto chino y heredar las clases en CharacterTextSplitterlangchain ChineseTextSplitter. Expresión regular sent_sep_patternpara que coincida con los delimitadores de oraciones chinas (como punto, signo de exclamación, hola, punto y coma, etc.):

# 中文文本切分类
class ChineseTextSplitter(CharacterTextSplitter):
    def __init__(self, pdf: bool = False, **kwargs):
        super().__init__(**kwargs)
        self.pdf = pdf

    def split_text(self, text: str) -> List[str]:
        if self.pdf:
            text = re.sub(r"\n{3,}", "\n", text)
            text = re.sub('\s', ' ', text)
            text = text.replace("\n\n", "")
        sent_sep_pattern = re.compile('([﹒﹔﹖﹗.。!?]["’”」』]{0,2}|(?=["‘“「『]{1,2}|$))')  # del :;
        sent_list = []
        for ele in sent_sep_pattern.split(text):
            if sent_sep_pattern.match(ele) and sent_list:
                sent_list[-1] += ele
            elif ele:
                sent_list.append(ele)
        return sent_list

3. Proceso gráfico

inserte la descripción de la imagen aquí

Referencia

[1] MedicalGPT: entrenamiento del modelo GPT médico [2
] Cómo manejar los límites de frecuencia . 4] Todo lo que necesita saber para crear su primera aplicación LLM hacia la ciencia de datos [5] Serie LLM | 15: Cómo usar LangChain para hacer preguntas y respuestas de documentos largos [6] Gran modelo de sistema de diálogo de base de conocimiento local. tx ingeniería técnica



Supongo que te gusta

Origin blog.csdn.net/qq_35812205/article/details/131741245
Recomendado
Clasificación