-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy path1_hola_langchain.py
132 lines (102 loc) · 4.67 KB
/
1_hola_langchain.py
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
# --- Carga de documents
import os
import requests
from langchain.document_loaders import PyPDFLoader
urls = [
'https://arxiv.org/pdf/2306.06031v1.pdf',
'https://arxiv.org/pdf/2306.12156v1.pdf',
'https://arxiv.org/pdf/2306.14289v1.pdf',
'https://arxiv.org/pdf/2305.10973v1.pdf',
'https://arxiv.org/pdf/2306.13643v1.pdf'
]
ml_papers = []
for i, url in enumerate(urls):
filename = f'paper{i+1}.pdf'
# Verifico si el archivo no ha sido descargado previamente
if not os.path.exists(filename):
response = requests.get(url)
with open(filename, 'wb') as f:
f.write(response.content)
print(f'Descargado {filename}')
else:
print(f'{filename} ya existe, cargando desde el disco.')
loader = PyPDFLoader(filename)
data = loader.load()
ml_papers.extend(data)
# Utiliza la lista ml_papers para acceder a los elementos de todos los documentos descargados
print('Contenido de ml_papers:')
print()
print(type(ml_papers), len(ml_papers), ml_papers[3])
# --- Split de documents
# Los documentos NO pueden ser procesados directamente por LLMs porque contienen demasiado texto, sin embargo, podemos
# particionarlo en conjuntos de texto más pequeños para entonces poder acceder a su información.
from langchain.text_splitter import RecursiveCharacterTextSplitter
# Cada partición contendrá 1500 palabras, y tendrán una intersección de 200, de modo que la cadena 2 comparte 200
# palabras con la cadena 1 y con la cadena 3
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1500,
chunk_overlap=200,
length_function=len
)
documents = text_splitter.split_documents(ml_papers)
# Ahora podemos revisar de nuevo la cantidad de `documentos` y ver un ejemplo del mismo
print(len(documents), documents[10])
# --- Embeddings e ingesta a base de datos vectorial
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from dotenv import load_dotenv
# leo el archivo keys.env y obtengo mi Api KEY de OpenAI
load_dotenv("../secret/keys.env")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# Es importante que quede seteado como una variable de entorno porque será utilizado más adelante
os.environ['OPENAI_API_KEY'] = OPENAI_API_KEY
# Crea un objeto capaz de convertir el texto a un vector utilizando como base el modelo de ADA-002 de OpenAI
# En este punto es importante que hayas seteado tu OPENAI API KEY como variable de entorno, para que puedas acceder
# a este servicio
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
# Con ayuda de Chroma, creamos un objeto vectorstore para almacenar las representaciones vectoriales de los textos
# contenidos en `documents` una cadena de texto previamente generada
vectorstore = Chroma.from_documents(
documents=documents,
embedding=embeddings
)
# Una vez que hayas creado la Base de datos vectorial, el parámetro search_kwargs `k` me permite definir hasta cuantos
# vectores similares voy a buscar al momento de encontrar información para una pregunta. `retriever` será entonces
# nuestra base de datos de vectores que servirá para añadir información reciente a los LLMs con el fin de responder
# preguntas.
retriever = vectorstore.as_retriever(
search_kwargs={"k": 3}
)
# --- Modelos de Chat y cadenas para consulta de información
from langchain.chat_models import ChatOpenAI
# Voy a crear un objeto `chat` de la clase ChatOpenAI indicando que el engine a utilizar será GPT 3.5 y cuya temperatura
# será 0 lo que signfica que tendrá respuestas muy restrictivas basadas únicamente en el texto que conoce y tendrá
# poca creatividad al momento de responder peticiones.
chat = ChatOpenAI(
openai_api_key=OPENAI_API_KEY,
model_name='gpt-3.5-turbo',
temperature=0.0
)
from langchain.chains import RetrievalQA
# Finalmente, creamos una cadena `chain` del tipo `Question Answer` pregunta-respuesta. Como LLM utilizará al objeto
# `chat` que es una instancia de ChatGPT 3.5, el tipo de cadena es `stuff` que significa que vamos a utilizar tanta
# información como quepa en el prompt, y finalmente el `retriever` será la base de datos vectoriales que hemos definido
# previamente.
qa_chain = RetrievalQA.from_chain_type(
llm=chat,
chain_type="stuff",
retriever=retriever
)
# Vamos a poner a prueba nuestra cadena de preguntas y respuestas:
query = "qué es fingpt?"
print("--->", query)
print(qa_chain.run(query))
query = "qué hace complicado entrenar un modelo como el fingpt?"
print("--->", query)
print(qa_chain.run(query))
query = "qué es fast segment?"
print("--->", query)
print(qa_chain.run(query))
query = "cuál es la diferencia entre fast sam y mobile sam?"
print("--->", query)
print(qa_chain.run(query))