Spaces:
Sleeping
Sleeping
bachephysicdun
commited on
Commit
·
5a2b2d3
1
Parent(s):
20f2960
add simple stream and incomplete files
Browse files- Dockerfile +3 -1
- __init__.py +0 -0
- __pycache__/app.cpython-311.pyc +0 -0
- app/.ipynb_checkpoints/Untitled-checkpoint.ipynb +6 -0
- app/.ipynb_checkpoints/Untitled1-checkpoint.ipynb +6 -0
- app/.ipynb_checkpoints/Untitled2-checkpoint.ipynb +6 -0
- app/__init__.py +0 -0
- app/__pycache__/__init__.cpython-311.pyc +0 -0
- app/__pycache__/callbacks.cpython-311.pyc +0 -0
- app/__pycache__/chains.cpython-311.pyc +0 -0
- app/__pycache__/crud.cpython-311.pyc +0 -0
- app/__pycache__/data_indexing.cpython-311.pyc +0 -0
- app/__pycache__/data_indexing.cpython-312.pyc +0 -0
- app/__pycache__/database.cpython-311.pyc +0 -0
- app/__pycache__/database.cpython-312.pyc +0 -0
- app/__pycache__/main.cpython-311.pyc +0 -0
- app/__pycache__/models.cpython-311.pyc +0 -0
- app/__pycache__/models.cpython-312.pyc +0 -0
- app/__pycache__/prompts.cpython-311.pyc +0 -0
- app/__pycache__/prompts.cpython-312.pyc +0 -0
- app/__pycache__/schemas.cpython-311.pyc +0 -0
- app/__pycache__/schemas.cpython-312.pyc +0 -0
- app/callbacks.py +24 -0
- app/chains.py +55 -0
- app/crud.py +23 -0
- app/data_indexing.py +150 -0
- app/database.py +55 -0
- app/main.py +94 -0
- app/models.py +55 -0
- app/prompts.py +58 -0
- app/schemas.py +18 -0
- app/test.db +0 -0
- check.ipynb +229 -0
Dockerfile
CHANGED
@@ -16,4 +16,6 @@ RUN pip install --no-cache-dir --upgrade -r requirements.txt
|
|
16 |
# Again, ensure the copied files are owned by 'user'
|
17 |
COPY --chown=user . /app
|
18 |
# Specify the command to run when the container starts
|
19 |
-
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
|
|
|
|
|
16 |
# Again, ensure the copied files are owned by 'user'
|
17 |
COPY --chown=user . /app
|
18 |
# Specify the command to run when the container starts
|
19 |
+
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
20 |
+
# Pass the secret variable to the application
|
21 |
+
RUN --mount=type=secret,id=HF_TOKEN,mode=0444,required=true
|
__init__.py
ADDED
File without changes
|
__pycache__/app.cpython-311.pyc
ADDED
Binary file (493 Bytes). View file
|
|
app/.ipynb_checkpoints/Untitled-checkpoint.ipynb
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [],
|
3 |
+
"metadata": {},
|
4 |
+
"nbformat": 4,
|
5 |
+
"nbformat_minor": 5
|
6 |
+
}
|
app/.ipynb_checkpoints/Untitled1-checkpoint.ipynb
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [],
|
3 |
+
"metadata": {},
|
4 |
+
"nbformat": 4,
|
5 |
+
"nbformat_minor": 5
|
6 |
+
}
|
app/.ipynb_checkpoints/Untitled2-checkpoint.ipynb
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [],
|
3 |
+
"metadata": {},
|
4 |
+
"nbformat": 4,
|
5 |
+
"nbformat_minor": 5
|
6 |
+
}
|
app/__init__.py
ADDED
File without changes
|
app/__pycache__/__init__.cpython-311.pyc
ADDED
Binary file (183 Bytes). View file
|
|
app/__pycache__/callbacks.cpython-311.pyc
ADDED
Binary file (1.78 kB). View file
|
|
app/__pycache__/chains.cpython-311.pyc
ADDED
Binary file (1.12 kB). View file
|
|
app/__pycache__/crud.cpython-311.pyc
ADDED
Binary file (1.44 kB). View file
|
|
app/__pycache__/data_indexing.cpython-311.pyc
ADDED
Binary file (7.12 kB). View file
|
|
app/__pycache__/data_indexing.cpython-312.pyc
ADDED
Binary file (5.75 kB). View file
|
|
app/__pycache__/database.cpython-311.pyc
ADDED
Binary file (705 Bytes). View file
|
|
app/__pycache__/database.cpython-312.pyc
ADDED
Binary file (610 Bytes). View file
|
|
app/__pycache__/main.cpython-311.pyc
ADDED
Binary file (2.7 kB). View file
|
|
app/__pycache__/models.cpython-311.pyc
ADDED
Binary file (1.83 kB). View file
|
|
app/__pycache__/models.cpython-312.pyc
ADDED
Binary file (1.51 kB). View file
|
|
app/__pycache__/prompts.cpython-311.pyc
ADDED
Binary file (1.76 kB). View file
|
|
app/__pycache__/prompts.cpython-312.pyc
ADDED
Binary file (1.59 kB). View file
|
|
app/__pycache__/schemas.cpython-311.pyc
ADDED
Binary file (1.12 kB). View file
|
|
app/__pycache__/schemas.cpython-312.pyc
ADDED
Binary file (908 Bytes). View file
|
|
app/callbacks.py
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Dict, Any, List
|
2 |
+
from langchain_core.callbacks import BaseCallbackHandler
|
3 |
+
import schemas
|
4 |
+
import crud
|
5 |
+
|
6 |
+
|
7 |
+
class LogResponseCallback(BaseCallbackHandler):
|
8 |
+
|
9 |
+
def __init__(self, user_request: schemas.UserRequest, db):
|
10 |
+
super().__init__()
|
11 |
+
self.user_request = user_request
|
12 |
+
self.db = db
|
13 |
+
|
14 |
+
def on_llm_end(self, outputs: Dict[str, Any], **kwargs: Any) -> Any:
|
15 |
+
"""Run when llm ends running."""
|
16 |
+
# TODO: The function on_llm_end is going to be called when the LLM stops sending
|
17 |
+
# the response. Use the crud.add_message function to capture that response.
|
18 |
+
raise NotImplemented
|
19 |
+
|
20 |
+
def on_llm_start(
|
21 |
+
self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
|
22 |
+
) -> Any:
|
23 |
+
for prompt in prompts:
|
24 |
+
print(prompt)
|
app/chains.py
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#%%
|
2 |
+
import os
|
3 |
+
from dotenv import load_dotenv
|
4 |
+
load_dotenv('../../.env')
|
5 |
+
|
6 |
+
from langchain_huggingface import HuggingFaceEndpoint
|
7 |
+
from langchain_core.runnables import RunnablePassthrough
|
8 |
+
import schemas
|
9 |
+
from prompts import (
|
10 |
+
raw_prompt,
|
11 |
+
format_context,
|
12 |
+
tokenizer
|
13 |
+
)
|
14 |
+
from data_indexing import DataIndexer
|
15 |
+
|
16 |
+
|
17 |
+
# data_indexer = DataIndexer()
|
18 |
+
|
19 |
+
llm = HuggingFaceEndpoint(
|
20 |
+
repo_id="meta-llama/Meta-Llama-3-8B-Instruct",
|
21 |
+
huggingfacehub_api_token=os.environ['HF_TOKEN'],
|
22 |
+
max_new_tokens=512,
|
23 |
+
stop_sequences=[tokenizer.eos_token],
|
24 |
+
streaming=True,
|
25 |
+
)
|
26 |
+
|
27 |
+
simple_chain = (raw_prompt | llm).with_types(input_type=schemas.UserQuestion)
|
28 |
+
# %%
|
29 |
+
|
30 |
+
# data_indexer = DataIndexer()
|
31 |
+
|
32 |
+
# # TODO: create formatted_chain by piping raw_prompt_formatted and the LLM endpoint.
|
33 |
+
# formatted_chain = None
|
34 |
+
|
35 |
+
# # TODO: use history_prompt_formatted and HistoryInput to create the history_chain
|
36 |
+
# history_chain = None
|
37 |
+
|
38 |
+
# # TODO: Let's construct the standalone_chain by piping standalone_prompt_formatted with the LLM
|
39 |
+
# standalone_chain = None
|
40 |
+
|
41 |
+
# input_1 = RunnablePassthrough.assign(new_question=standalone_chain)
|
42 |
+
# input_2 = {
|
43 |
+
# 'context': lambda x: format_context(data_indexer.search(x['new_question'])),
|
44 |
+
# 'standalone_question': lambda x: x['new_question']
|
45 |
+
# }
|
46 |
+
# input_to_rag_chain = input_1 | input_2
|
47 |
+
|
48 |
+
# # TODO: use input_to_rag_chain, rag_prompt_formatted,
|
49 |
+
# # HistoryInput and the LLM to build the rag_chain.
|
50 |
+
# rag_chain = None
|
51 |
+
|
52 |
+
# # TODO: Implement the filtered_rag_chain. It should be the
|
53 |
+
# # same as the rag_chain but with hybrid_search = True.
|
54 |
+
# filtered_rag_chain = None
|
55 |
+
|
app/crud.py
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sqlalchemy.orm import Session
|
2 |
+
import models, schemas
|
3 |
+
|
4 |
+
|
5 |
+
def get_or_create_user(db: Session, username: str):
|
6 |
+
user = db.query(models.User).filter(models.User.username == username).first()
|
7 |
+
if not user:
|
8 |
+
user = models.User(username=username)
|
9 |
+
db.add(user)
|
10 |
+
db.commit()
|
11 |
+
db.refresh(user)
|
12 |
+
return user
|
13 |
+
|
14 |
+
def add_message(db: Session, message: schemas.MessageBase, username: str):
|
15 |
+
# TODO: Implement the add_message function. It should:
|
16 |
+
# - get or create the user with the username
|
17 |
+
# - create a models.Message instance
|
18 |
+
# - pass the retrieved user to the message instance
|
19 |
+
# - save the message instance to the database
|
20 |
+
raise NotImplemented
|
21 |
+
|
22 |
+
def get_user_chat_history(db: Session, username: str):
|
23 |
+
raise NotImplemented
|
app/data_indexing.py
ADDED
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import uuid
|
3 |
+
from pathlib import Path
|
4 |
+
from pinecone.grpc import PineconeGRPC as Pinecone
|
5 |
+
from pinecone import ServerlessSpec
|
6 |
+
from langchain_community.vectorstores import Chroma
|
7 |
+
from langchain_openai import OpenAIEmbeddings
|
8 |
+
|
9 |
+
current_dir = Path(__file__).resolve().parent
|
10 |
+
|
11 |
+
|
12 |
+
class DataIndexer:
|
13 |
+
|
14 |
+
source_file = os.path.join(current_dir, 'sources.txt')
|
15 |
+
|
16 |
+
def __init__(self, index_name='langchain-repo') -> None:
|
17 |
+
|
18 |
+
# TODO: choose your embedding model
|
19 |
+
# self.embedding_client = InferenceClient(
|
20 |
+
# "dunzhang/stella_en_1.5B_v5",
|
21 |
+
# token=os.environ['HF_TOKEN'],
|
22 |
+
# )
|
23 |
+
self.embedding_client = OpenAIEmbeddings()
|
24 |
+
self.index_name = index_name
|
25 |
+
self.pinecone_client = Pinecone(api_key=os.environ.get('PINECONE_API_KEY'))
|
26 |
+
|
27 |
+
if index_name not in self.pinecone_client.list_indexes().names():
|
28 |
+
# TODO: create your index if it doesn't exist. Use the create_index function.
|
29 |
+
# Make sure to choose the dimension that corresponds to your embedding model
|
30 |
+
pass
|
31 |
+
|
32 |
+
self.index = self.pinecone_client.Index(self.index_name)
|
33 |
+
# TODO: make sure to build the index.
|
34 |
+
self.source_index = None
|
35 |
+
|
36 |
+
def get_source_index(self):
|
37 |
+
if not os.path.isfile(self.source_file):
|
38 |
+
print('No source file')
|
39 |
+
return None
|
40 |
+
|
41 |
+
print('create source index')
|
42 |
+
|
43 |
+
with open(self.source_file, 'r') as file:
|
44 |
+
sources = file.readlines()
|
45 |
+
|
46 |
+
sources = [s.rstrip('\n') for s in sources]
|
47 |
+
vectorstore = Chroma.from_texts(
|
48 |
+
sources, embedding=self.embedding_client
|
49 |
+
)
|
50 |
+
return vectorstore
|
51 |
+
|
52 |
+
def index_data(self, docs, batch_size=32):
|
53 |
+
|
54 |
+
with open(self.source_file, 'a') as file:
|
55 |
+
for doc in docs:
|
56 |
+
file.writelines(doc.metadata['source'] + '\n')
|
57 |
+
|
58 |
+
for i in range(0, len(docs), batch_size):
|
59 |
+
batch = docs[i: i + batch_size]
|
60 |
+
|
61 |
+
# TODO: create a list of the vector representations of each text data in the batch
|
62 |
+
# TODO: choose your embedding model
|
63 |
+
# values = self.embedding_client.embed_documents([
|
64 |
+
# doc.page_content for doc in batch
|
65 |
+
# ])
|
66 |
+
|
67 |
+
# values = self.embedding_client.feature_extraction([
|
68 |
+
# doc.page_content for doc in batch
|
69 |
+
# ])
|
70 |
+
values = None
|
71 |
+
|
72 |
+
# TODO: create a list of unique identifiers for each element in the batch with the uuid package.
|
73 |
+
vector_ids = None
|
74 |
+
|
75 |
+
# TODO: create a list of dictionaries representing the metadata. Capture the text data
|
76 |
+
# with the "text" key, and make sure to capture the rest of the doc.metadata.
|
77 |
+
metadatas = None
|
78 |
+
|
79 |
+
# create a list of dictionaries with keys "id" (the unique identifiers), "values"
|
80 |
+
# (the vector representation), and "metadata" (the metadata).
|
81 |
+
vectors = [{
|
82 |
+
'id': vector_id,
|
83 |
+
'values': value,
|
84 |
+
'metadata': metadata
|
85 |
+
} for vector_id, value, metadata in zip(vector_ids, values, metadatas)]
|
86 |
+
|
87 |
+
try:
|
88 |
+
# TODO: Use the function upsert to upload the data to the database.
|
89 |
+
upsert_response = None
|
90 |
+
print(upsert_response)
|
91 |
+
except Exception as e:
|
92 |
+
print(e)
|
93 |
+
|
94 |
+
def search(self, text_query, top_k=5, hybrid_search=False):
|
95 |
+
|
96 |
+
filter = None
|
97 |
+
if hybrid_search and self.source_index:
|
98 |
+
# I implemented the filtering process to pull the 50 most relevant file names
|
99 |
+
# to the question. Make sure to adjust this number as you see fit.
|
100 |
+
source_docs = self.source_index.similarity_search(text_query, 50)
|
101 |
+
filter = {"source": {"$in":[doc.page_content for doc in source_docs]}}
|
102 |
+
|
103 |
+
# TODO: embed the text_query by using the embedding model
|
104 |
+
# TODO: choose your embedding model
|
105 |
+
# vector = self.embedding_client.feature_extraction(text_query)
|
106 |
+
# vector = self.embedding_client.embed_query(text_query)
|
107 |
+
vector = None
|
108 |
+
|
109 |
+
# TODO: use the vector representation of the text_query to
|
110 |
+
# search the database by using the query function.
|
111 |
+
result = None
|
112 |
+
|
113 |
+
docs = []
|
114 |
+
for res in result["matches"]:
|
115 |
+
# TODO: From the result's metadata, extract the "text" element.
|
116 |
+
pass
|
117 |
+
|
118 |
+
return docs
|
119 |
+
|
120 |
+
|
121 |
+
if __name__ == '__main__':
|
122 |
+
|
123 |
+
from langchain_community.document_loaders import GitLoader
|
124 |
+
from langchain_text_splitters import (
|
125 |
+
Language,
|
126 |
+
RecursiveCharacterTextSplitter,
|
127 |
+
)
|
128 |
+
|
129 |
+
loader = GitLoader(
|
130 |
+
clone_url="https://github.com/langchain-ai/langchain",
|
131 |
+
repo_path="./code_data/langchain_repo/",
|
132 |
+
branch="master",
|
133 |
+
)
|
134 |
+
|
135 |
+
python_splitter = RecursiveCharacterTextSplitter.from_language(
|
136 |
+
language=Language.PYTHON, chunk_size=10000, chunk_overlap=100
|
137 |
+
)
|
138 |
+
|
139 |
+
docs = loader.load()
|
140 |
+
docs = [doc for doc in docs if doc.metadata['file_type'] in ['.py', '.md']]
|
141 |
+
docs = [doc for doc in docs if len(doc.page_content) < 50000]
|
142 |
+
docs = python_splitter.split_documents(docs)
|
143 |
+
for doc in docs:
|
144 |
+
doc.page_content = '# {}\n\n'.format(doc.metadata['source']) + doc.page_content
|
145 |
+
|
146 |
+
indexer = DataIndexer()
|
147 |
+
with open('/app/sources.txt', 'a') as file:
|
148 |
+
for doc in docs:
|
149 |
+
file.writelines(doc.metadata['source'] + '\n')
|
150 |
+
indexer.index_data(docs)
|
app/database.py
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#%%
|
2 |
+
|
3 |
+
# create_engine: This function creates a new SQLAlchemy “engine,”
|
4 |
+
# which is an interface to the database. It acts as the core connection to
|
5 |
+
# your database and manages the communication between your Python code and the database.
|
6 |
+
from sqlalchemy import create_engine
|
7 |
+
|
8 |
+
# declarative_base: This function is used to create a base class for our ORM models.
|
9 |
+
# All of your database table classes (models) will inherit from this base class.
|
10 |
+
# This base class also ties each model to a corresponding table in the database.
|
11 |
+
from sqlalchemy.ext.declarative import declarative_base
|
12 |
+
|
13 |
+
# sessionmaker: This is a factory function for creating new Session objects.
|
14 |
+
# Sessions are used to manage the operations (queries, updates, etc.) on
|
15 |
+
# the database in a transaction-safe way. They provide an interface for
|
16 |
+
# interacting with the database.
|
17 |
+
from sqlalchemy.orm import sessionmaker
|
18 |
+
|
19 |
+
# This line defines the URL for your database connection.
|
20 |
+
# SQLAlchemy uses this URL to determine what type of database you’re
|
21 |
+
# connecting to, and where it’s located.
|
22 |
+
# sqlite:// tells SQLAlchemy that you are using SQLite as the database engine.
|
23 |
+
# ./test.db specifies the relative path to the database file (test.db) in the
|
24 |
+
# current directory (./). SQLite stores the entire database as a single file on disk
|
25 |
+
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
|
26 |
+
|
27 |
+
# This line creates the database engine by passing the SQLALCHEMY_DATABASE_URL to the
|
28 |
+
# create_engine function. The engine is responsible for managing the connection to the database.
|
29 |
+
# connect_args={"check_same_thread": False}: This argument is specific to SQLite. By default,
|
30 |
+
# SQLite does not allow multiple threads to interact with the database. The check_same_thread
|
31 |
+
# argument disables this check, allowing the engine to be used in a multi-threaded environment.
|
32 |
+
# This is necessary for many web applications (like FastAPI) that might have multiple requests
|
33 |
+
# hitting the database simultaneously.
|
34 |
+
engine = create_engine(
|
35 |
+
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
|
36 |
+
)
|
37 |
+
|
38 |
+
# you create a factory for database sessions. SessionLocal will be used to create individual sessions,
|
39 |
+
# which are needed to interact with the database (querying data, inserting/updating records, etc.).
|
40 |
+
# 1. autocommit=False: This means that changes (inserts, updates, deletes) to the database will not be
|
41 |
+
# committed automatically. You will need to explicitly commit transactions using session.commit().
|
42 |
+
# This gives you better control over when data is saved.
|
43 |
+
# 2. autoflush=False: This disables automatic flushing. Flushing is the process of sending any pending
|
44 |
+
# changes to the database before executing queries. With autoflush=False, the session will not
|
45 |
+
# automatically send updates to the database unless you explicitly tell it to by calling flush() or commit().
|
46 |
+
# It prevents unexpected database updates.
|
47 |
+
# 3. bind=engine: This ties the session to the database engine. Any session created with SessionLocal()
|
48 |
+
# will use the engine to communicate with the database.
|
49 |
+
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
50 |
+
|
51 |
+
# This line creates a base class for all of your ORM models (i.e., classes that represent database tables).
|
52 |
+
# Each model (class) will inherit from Base, and SQLAlchemy will use this base class to generate the
|
53 |
+
# necessary SQL statements to create tables and handle CRUD operations (Create, Read, Update, Delete).
|
54 |
+
Base = declarative_base()
|
55 |
+
# %%
|
app/main.py
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from langchain_core.runnables import Runnable
|
2 |
+
from langchain_core.callbacks import BaseCallbackHandler
|
3 |
+
from fastapi import FastAPI, Request, Depends
|
4 |
+
from sse_starlette.sse import EventSourceResponse
|
5 |
+
from langserve.serialization import WellKnownLCSerializer
|
6 |
+
from typing import List
|
7 |
+
from sqlalchemy.orm import Session
|
8 |
+
|
9 |
+
import schemas
|
10 |
+
from chains import simple_chain
|
11 |
+
import crud, models, schemas
|
12 |
+
from database import SessionLocal, engine
|
13 |
+
from callbacks import LogResponseCallback
|
14 |
+
|
15 |
+
|
16 |
+
models.Base.metadata.create_all(bind=engine)
|
17 |
+
|
18 |
+
app = FastAPI()
|
19 |
+
|
20 |
+
# def get_db():
|
21 |
+
# db = SessionLocal()
|
22 |
+
# try:
|
23 |
+
# yield db
|
24 |
+
# finally:
|
25 |
+
# db.close()
|
26 |
+
|
27 |
+
|
28 |
+
async def generate_stream(input_data: schemas.BaseModel, runnable: Runnable, callbacks: List[BaseCallbackHandler]=[]):
|
29 |
+
for output in runnable.stream(input_data.dict(), config={"callbacks": callbacks}):
|
30 |
+
data = WellKnownLCSerializer().dumps(output).decode("utf-8")
|
31 |
+
yield {'data': data, "event": "data"}
|
32 |
+
yield {"event": "end"}
|
33 |
+
|
34 |
+
|
35 |
+
@app.post("/simple/stream")
|
36 |
+
async def simple_stream(request: Request):
|
37 |
+
data = await request.json()
|
38 |
+
user_question = schemas.UserQuestion(**data['input'])
|
39 |
+
return EventSourceResponse(generate_stream(user_question, simple_chain))
|
40 |
+
|
41 |
+
|
42 |
+
# @app.post("/formatted/stream")
|
43 |
+
# async def formatted_stream(request: Request):
|
44 |
+
# # TODO: use the formatted_chain to implement the "/formatted/stream" endpoint.
|
45 |
+
# raise NotImplemented
|
46 |
+
|
47 |
+
|
48 |
+
# def get_db():
|
49 |
+
# db = SessionLocal()
|
50 |
+
# try:
|
51 |
+
# yield db
|
52 |
+
# finally:
|
53 |
+
# db.close()
|
54 |
+
|
55 |
+
# @app.post("/history/stream")
|
56 |
+
# async def history_stream(request: Request, db: Session = Depends(get_db)):
|
57 |
+
# # TODO: Let's implement the "/history/stream" endpoint. The endpoint should follow those steps:
|
58 |
+
# # - The endpoint receives the request
|
59 |
+
# # - The request is parsed into a user request
|
60 |
+
# # - The user request is used to pull the chat history of the user
|
61 |
+
# # - We add as part of the user history the current question by using add_message.
|
62 |
+
# # - We create an instance of HistoryInput by using format_chat_history.
|
63 |
+
# # - We use the history input within the history chain.
|
64 |
+
# raise NotImplemented
|
65 |
+
|
66 |
+
|
67 |
+
# @app.post("/rag/stream")
|
68 |
+
# async def rag_stream(request: Request, db: Session = Depends(get_db)):
|
69 |
+
# # TODO: Let's implement the "/rag/stream" endpoint. The endpoint should follow those steps:
|
70 |
+
# # - The endpoint receives the request
|
71 |
+
# # - The request is parsed into a user request
|
72 |
+
# # - The user request is used to pull the chat history of the user
|
73 |
+
# # - We add as part of the user history the current question by using add_message.
|
74 |
+
# # - We create an instance of HistoryInput by using format_chat_history.
|
75 |
+
# # - We use the history input within the rag chain.
|
76 |
+
# raise NotImplemented
|
77 |
+
|
78 |
+
|
79 |
+
# @app.post("/filtered_rag/stream")
|
80 |
+
# async def filtered_rag_stream(request: Request, db: Session = Depends(get_db)):
|
81 |
+
# # TODO: Let's implement the "/filtered_rag/stream" endpoint. The endpoint should follow those steps:
|
82 |
+
# # - The endpoint receives the request
|
83 |
+
# # - The request is parsed into a user request
|
84 |
+
# # - The user request is used to pull the chat history of the user
|
85 |
+
# # - We add as part of the user history the current question by using add_message.
|
86 |
+
# # - We create an instance of HistoryInput by using format_chat_history.
|
87 |
+
# # - We use the history input within the filtered rag chain.
|
88 |
+
# raise NotImplemented
|
89 |
+
|
90 |
+
|
91 |
+
|
92 |
+
if __name__ == "__main__":
|
93 |
+
import uvicorn
|
94 |
+
uvicorn.run("main:app", host="localhost", reload=True, port=8000)
|
app/models.py
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sqlalchemy import Column, ForeignKey, Integer, String, DateTime
|
2 |
+
from sqlalchemy.orm import relationship
|
3 |
+
|
4 |
+
from datetime import datetime
|
5 |
+
|
6 |
+
from database import Base
|
7 |
+
|
8 |
+
class User(Base):
|
9 |
+
|
10 |
+
# This defines the name of the table in the database.
|
11 |
+
# Here, the class User is mapped to a table called users.
|
12 |
+
__tablename__ = "users"
|
13 |
+
__table_args__ = {'extend_existing': True}
|
14 |
+
|
15 |
+
# This line defines a column called id in the users table.
|
16 |
+
# Integer: The data type of this column is an integer.
|
17 |
+
# primary_key=True: This makes the id column the primary key
|
18 |
+
# for the users table, meaning each row will have a unique id.
|
19 |
+
# index=True: This creates an index on the id column, making
|
20 |
+
# lookups by id faster.
|
21 |
+
id = Column(Integer, primary_key=True, index=True)
|
22 |
+
|
23 |
+
# This line defines a column called username.
|
24 |
+
username = Column(String, unique=True, index=True)
|
25 |
+
|
26 |
+
# This establishes a relationship between the User model
|
27 |
+
# and a related model called Message.
|
28 |
+
# relationship("Message"): This creates a one-to-many relationship between User and Message.
|
29 |
+
# It indicates that each user can have many associated messages
|
30 |
+
# (the relationship is “one user to many messages”).
|
31 |
+
# back_populates="user": This specifies that the relationship is bidirectional,
|
32 |
+
# meaning the Message model will also have a corresponding relationship with User.
|
33 |
+
# The back_populates="user" part tells SQLAlchemy to link the relationship on the
|
34 |
+
# Message side back to the user field, creating a mutual relationship.
|
35 |
+
messages = relationship("Message", back_populates="user")
|
36 |
+
|
37 |
+
|
38 |
+
# TODO: Implement the Message SQLAlchemy model. Message should have a primary key,
|
39 |
+
# a message attribute to store the content of messages, a type, AI or Human,
|
40 |
+
# depending on if it is a user question or an AI response, a timestamp to
|
41 |
+
# order by time and a user attribute to get the user instance associated
|
42 |
+
# with the message. We also need a user_id that will use the User.id
|
43 |
+
# attribute as a foreign key.
|
44 |
+
|
45 |
+
class Message(Base):
|
46 |
+
__tablename__ = "messages"
|
47 |
+
__table_args__ = {'extend_existing': True}
|
48 |
+
|
49 |
+
id = id = Column(Integer, primary_key=True, index=True)
|
50 |
+
message = Column(String, nullable=False)
|
51 |
+
type = Column(String(50), nullable=False)
|
52 |
+
timestamp = Column(DateTime, default=datetime.utcnow, nullable=False)
|
53 |
+
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
54 |
+
|
55 |
+
user = relationship("User", back_populates="messages")
|
app/prompts.py
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#%%
|
2 |
+
import os
|
3 |
+
# from dotenv import load_dotenv
|
4 |
+
# load_dotenv('../../.env')
|
5 |
+
|
6 |
+
from langchain_core.prompts import PromptTemplate
|
7 |
+
from typing import List
|
8 |
+
|
9 |
+
from transformers import AutoTokenizer
|
10 |
+
from huggingface_hub import login
|
11 |
+
|
12 |
+
import models
|
13 |
+
|
14 |
+
|
15 |
+
login(os.environ['HF_TOKEN'])
|
16 |
+
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct")
|
17 |
+
|
18 |
+
def format_prompt(prompt) -> PromptTemplate:
|
19 |
+
# TODO: format the input prompt by using the model specific instruction template
|
20 |
+
# TODO: return a langchain PromptTemplate
|
21 |
+
raise NotImplemented
|
22 |
+
|
23 |
+
def format_chat_history(messages: List[models.Message]):
|
24 |
+
# TODO: implement format_chat_history to format
|
25 |
+
# the list of Message into a text of chat history.
|
26 |
+
raise NotImplemented
|
27 |
+
|
28 |
+
def format_context(docs: List[str]):
|
29 |
+
# TODO: the output of the DataIndexer.search is a list of text,
|
30 |
+
# so we need to concatenate that list into a text that can fit into
|
31 |
+
# the rag_prompt_formatted. Implement format_context that takes a
|
32 |
+
# like of strings and returns the context as one string.
|
33 |
+
raise NotImplemented
|
34 |
+
|
35 |
+
raw_prompt = "{question}"
|
36 |
+
|
37 |
+
# TODO: Create the history_prompt prompt that will capture the question and the conversation history.
|
38 |
+
# The history_prompt needs a {chat_history} placeholder and a {question} placeholder.
|
39 |
+
history_prompt: str = None
|
40 |
+
|
41 |
+
# TODO: Create the standalone_prompt prompt that will capture the question and the chat history
|
42 |
+
# to generate a standalone question. It needs a {chat_history} placeholder and a {question} placeholder,
|
43 |
+
standalone_prompt: str = None
|
44 |
+
|
45 |
+
# TODO: Create the rag_prompt that will capture the context and the standalone question to generate
|
46 |
+
# a final answer to the question.
|
47 |
+
rag_prompt: str = None
|
48 |
+
|
49 |
+
# TODO: create raw_prompt_formatted by using format_prompt
|
50 |
+
raw_prompt_formatted = None
|
51 |
+
raw_prompt = PromptTemplate.from_template(raw_prompt)
|
52 |
+
|
53 |
+
# TODO: use format_prompt to create history_prompt_formatted
|
54 |
+
history_prompt_formatted: PromptTemplate = None
|
55 |
+
# TODO: use format_prompt to create standalone_prompt_formatted
|
56 |
+
standalone_prompt_formatted: PromptTemplate = None
|
57 |
+
# TODO: use format_prompt to create rag_prompt_formatted
|
58 |
+
rag_prompt_formatted: PromptTemplate = None
|
app/schemas.py
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
|
3 |
+
class UserQuestion(BaseModel):
|
4 |
+
question: str
|
5 |
+
|
6 |
+
# TODO: create a HistoryInput data model with a chat_history and question attributes.
|
7 |
+
class HistoryInput(BaseModel):
|
8 |
+
pass
|
9 |
+
|
10 |
+
# TODO: let's create a UserRequest data model with a question and username attribute.
|
11 |
+
# This will be used to parse the input request.
|
12 |
+
class UserRequest(BaseModel):
|
13 |
+
username: str
|
14 |
+
|
15 |
+
# TODO: implement MessageBase as a schema mapping from the database model to the
|
16 |
+
# FastAPI data model. Basically MessageBase should have the same attributes as models.Message
|
17 |
+
class MessageBase(BaseModel):
|
18 |
+
pass
|
app/test.db
ADDED
Binary file (24.6 kB). View file
|
|
check.ipynb
ADDED
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": 1,
|
6 |
+
"metadata": {},
|
7 |
+
"outputs": [],
|
8 |
+
"source": [
|
9 |
+
"%load_ext autoreload\n",
|
10 |
+
"%autoreload 2"
|
11 |
+
]
|
12 |
+
},
|
13 |
+
{
|
14 |
+
"cell_type": "code",
|
15 |
+
"execution_count": 2,
|
16 |
+
"metadata": {},
|
17 |
+
"outputs": [
|
18 |
+
{
|
19 |
+
"data": {
|
20 |
+
"text/plain": [
|
21 |
+
"True"
|
22 |
+
]
|
23 |
+
},
|
24 |
+
"execution_count": 2,
|
25 |
+
"metadata": {},
|
26 |
+
"output_type": "execute_result"
|
27 |
+
}
|
28 |
+
],
|
29 |
+
"source": [
|
30 |
+
"import requests\n",
|
31 |
+
"import os\n",
|
32 |
+
"\n",
|
33 |
+
"from dotenv import load_dotenv\n",
|
34 |
+
"load_dotenv()"
|
35 |
+
]
|
36 |
+
},
|
37 |
+
{
|
38 |
+
"cell_type": "code",
|
39 |
+
"execution_count": 3,
|
40 |
+
"metadata": {},
|
41 |
+
"outputs": [
|
42 |
+
{
|
43 |
+
"data": {
|
44 |
+
"text/plain": [
|
45 |
+
"'World!'"
|
46 |
+
]
|
47 |
+
},
|
48 |
+
"execution_count": 3,
|
49 |
+
"metadata": {},
|
50 |
+
"output_type": "execute_result"
|
51 |
+
}
|
52 |
+
],
|
53 |
+
"source": [
|
54 |
+
"url = 'https://bachephysicdun-backend.hf.space'\n",
|
55 |
+
"response = requests.get(url)\n",
|
56 |
+
"response.json()['Hello']"
|
57 |
+
]
|
58 |
+
},
|
59 |
+
{
|
60 |
+
"cell_type": "code",
|
61 |
+
"execution_count": 4,
|
62 |
+
"metadata": {},
|
63 |
+
"outputs": [],
|
64 |
+
"source": [
|
65 |
+
"from app.data_indexing import DataIndexer"
|
66 |
+
]
|
67 |
+
},
|
68 |
+
{
|
69 |
+
"cell_type": "code",
|
70 |
+
"execution_count": 5,
|
71 |
+
"metadata": {},
|
72 |
+
"outputs": [
|
73 |
+
{
|
74 |
+
"data": {
|
75 |
+
"text/plain": [
|
76 |
+
"sqlalchemy.orm.decl_api.Base"
|
77 |
+
]
|
78 |
+
},
|
79 |
+
"execution_count": 5,
|
80 |
+
"metadata": {},
|
81 |
+
"output_type": "execute_result"
|
82 |
+
}
|
83 |
+
],
|
84 |
+
"source": [
|
85 |
+
"from app.database import Base\n",
|
86 |
+
"\n",
|
87 |
+
"Base"
|
88 |
+
]
|
89 |
+
},
|
90 |
+
{
|
91 |
+
"cell_type": "code",
|
92 |
+
"execution_count": 6,
|
93 |
+
"metadata": {},
|
94 |
+
"outputs": [],
|
95 |
+
"source": [
|
96 |
+
"import sys\n",
|
97 |
+
"sys.path.append('./app/')\n",
|
98 |
+
"from app.models import User, Message"
|
99 |
+
]
|
100 |
+
},
|
101 |
+
{
|
102 |
+
"cell_type": "code",
|
103 |
+
"execution_count": 7,
|
104 |
+
"metadata": {},
|
105 |
+
"outputs": [
|
106 |
+
{
|
107 |
+
"name": "stdout",
|
108 |
+
"output_type": "stream",
|
109 |
+
"text": [
|
110 |
+
"The token has not been saved to the git credentials helper. Pass `add_to_git_credential=True` in this function directly or `--add-to-git-credential` if using via `huggingface-cli` if you want to set the git credential as well.\n",
|
111 |
+
"Token is valid (permission: fineGrained).\n",
|
112 |
+
"Your token has been saved to /Users/amin/.cache/huggingface/token\n",
|
113 |
+
"Login successful\n",
|
114 |
+
"{'input_ids': [128000, 9906, 11, 1268, 527, 499, 30], 'attention_mask': [1, 1, 1, 1, 1, 1, 1]}\n"
|
115 |
+
]
|
116 |
+
}
|
117 |
+
],
|
118 |
+
"source": [
|
119 |
+
"import os\n",
|
120 |
+
"from transformers import AutoTokenizer\n",
|
121 |
+
"from huggingface_hub import login\n",
|
122 |
+
"\n",
|
123 |
+
"login(os.environ['HF_TOKEN'])\n",
|
124 |
+
"\n",
|
125 |
+
"# Load the tokenizer for the gated model\n",
|
126 |
+
"tokenizer = AutoTokenizer.from_pretrained(\"meta-llama/Meta-Llama-3-8B-Instruct\")\n",
|
127 |
+
"\n",
|
128 |
+
"# Example usage\n",
|
129 |
+
"text = \"Hello, how are you?\"\n",
|
130 |
+
"tokens = tokenizer(text)\n",
|
131 |
+
"\n",
|
132 |
+
"print(tokens)"
|
133 |
+
]
|
134 |
+
},
|
135 |
+
{
|
136 |
+
"cell_type": "code",
|
137 |
+
"execution_count": 8,
|
138 |
+
"metadata": {},
|
139 |
+
"outputs": [],
|
140 |
+
"source": [
|
141 |
+
"from huggingface_hub import InferenceClient\n",
|
142 |
+
"client = InferenceClient(\n",
|
143 |
+
" \"meta-llama/Meta-Llama-3-8B-Instruct\",\n",
|
144 |
+
" token=os.environ['HF_TOKEN'],\n",
|
145 |
+
")"
|
146 |
+
]
|
147 |
+
},
|
148 |
+
{
|
149 |
+
"cell_type": "code",
|
150 |
+
"execution_count": 11,
|
151 |
+
"metadata": {},
|
152 |
+
"outputs": [
|
153 |
+
{
|
154 |
+
"name": "stdout",
|
155 |
+
"output_type": "stream",
|
156 |
+
"text": [
|
157 |
+
" Linear regression is a statistical method that is used to create a linear equation that best predicts the relationship between two or more variables. The goal of linear regression is to create a model that can be used to make predictions about the value of the dependent variable (y) based on the value of one or more independent variables (x). Linear regression is a widely used and powerful tool for modeling the relationship between variables, and it has many applications in fields such as finance, economics, and medicine.\n",
|
158 |
+
"\n",
|
159 |
+
"How does Linear Regression work? Linear regression works by using a set of data points, where each data point represents a pair of values for the dependent and independent variables. The algorithm then finds the line that best fits the data points, by minimizing the sum of the squared errors between the predicted values and the actual values. The line that is found is called the regression line, and it is used to make predictions about the value of the dependent variable.\n",
|
160 |
+
"\n",
|
161 |
+
"There are several types of linear regression, including:\n",
|
162 |
+
"\n",
|
163 |
+
"* Simple Linear Regression: This type of linear regression involves a single independent variable and a single dependent variable.\n",
|
164 |
+
"* Multiple Linear Regression: This type of linear regression involves multiple independent variables and a single dependent variable.\n",
|
165 |
+
"* Polynomial Regression: This type of linear regression involves a polynomial equation, rather than a linear equation.\n",
|
166 |
+
"* Non-Linear Regression: This type of linear regression involves a non-linear equation, rather than a linear equation.\n",
|
167 |
+
"\n",
|
168 |
+
"What are the advantages and disadvantages of Linear Regression? The advantages of linear regression include:\n",
|
169 |
+
"\n",
|
170 |
+
"* It is a widely used and well-established statistical method.\n",
|
171 |
+
"* It is easy to interpret and understand.\n",
|
172 |
+
"* It can be used to make predictions about the value of the dependent variable.\n",
|
173 |
+
"* It can be used to identify the relationship between the independent and dependent variables.\n",
|
174 |
+
"\n",
|
175 |
+
"The disadvantages of linear regression include:\n",
|
176 |
+
"\n",
|
177 |
+
"* It assumes a linear relationship between the independent and dependent variables, which may not always be the case.\n",
|
178 |
+
"* It can be sensitive to outliers and noisy data.\n",
|
179 |
+
"* It can be difficult to interpret the results, especially for complex models.\n",
|
180 |
+
"* It can be sensitive to the choice of variables and the data used.\n",
|
181 |
+
"\n",
|
182 |
+
"What are some common applications of Linear Regression? Linear regression has many applications in fields such as:\n",
|
183 |
+
"\n",
|
184 |
+
"* Finance: Linear regression can be used to predict stock prices, interest rates, and other financial variables.\n",
|
185 |
+
"* Economics: Linear regression can be used to model the relationship between economic variables, such as GDP and unemployment rates.\n",
|
186 |
+
"* Medicine: Linear regression can be used to model the relationship between medical variables, such as blood pressure and heart rate.\n",
|
187 |
+
"* Marketing: Linear regression can"
|
188 |
+
]
|
189 |
+
}
|
190 |
+
],
|
191 |
+
"source": [
|
192 |
+
"from langserve import RemoteRunnable\n",
|
193 |
+
"chain = RemoteRunnable(\"http://localhost:8000/simple\")\n",
|
194 |
+
"stream = chain.stream(input={'question':'What is Linear Regression?'})\n",
|
195 |
+
"for chunk in stream:\n",
|
196 |
+
" print(chunk, end=\"\", flush=True)"
|
197 |
+
]
|
198 |
+
},
|
199 |
+
{
|
200 |
+
"cell_type": "code",
|
201 |
+
"execution_count": null,
|
202 |
+
"metadata": {},
|
203 |
+
"outputs": [],
|
204 |
+
"source": []
|
205 |
+
}
|
206 |
+
],
|
207 |
+
"metadata": {
|
208 |
+
"kernelspec": {
|
209 |
+
"display_name": "myenv",
|
210 |
+
"language": "python",
|
211 |
+
"name": "python3"
|
212 |
+
},
|
213 |
+
"language_info": {
|
214 |
+
"codemirror_mode": {
|
215 |
+
"name": "ipython",
|
216 |
+
"version": 3
|
217 |
+
},
|
218 |
+
"file_extension": ".py",
|
219 |
+
"mimetype": "text/x-python",
|
220 |
+
"name": "python",
|
221 |
+
"nbconvert_exporter": "python",
|
222 |
+
"pygments_lexer": "ipython3",
|
223 |
+
"version": "3.11.4"
|
224 |
+
},
|
225 |
+
"orig_nbformat": 4
|
226 |
+
},
|
227 |
+
"nbformat": 4,
|
228 |
+
"nbformat_minor": 2
|
229 |
+
}
|