LLMs and generative AI / Agents and LangChain
Leveraging LangChain, FAISS, and CTransformers in Python:
Contents
- Introduction to LangChain, FAISS, and CTransformers
- LangChain: Connecting Language Models to Data Sources
- FAISS: Efficient Similarity Search
- CTransformers: High-Performance Inference
- Combining LangChain and FAISS for Document Retrieval
- LangChain Chains: Composing Language Model Applications
- FAISS Indexing Techniques
- CTransformers: Model Quantization
- LangChain Agents: Autonomous Task Completion
- FAISS: Multi-GPU Support
- CTransformers: Custom Model Loading
- Real-Life Example: Document Question Answering System
- Real-Life Example: Semantic Image Search
- Additional Resources
Introduction to LangChain, FAISS, and CTransformers
LangChain is a framework for developing applications powered by language models. It provides tools to integrate with various data sources and enables complex reasoning capabilities. FAISS (Facebook AI Similarity Search) is a library for efficient similarity search and clustering of dense vectors. CTransformers is a Python binding for the Transformer models implemented in C/C++, offering high-performance inference capabilities.
import langchain
import faiss
import ctransformers
print(f"LangChain version: {langchain.__version__}")
print(f"FAISS version: {faiss.__version__}")
print(f"CTransformers version: {ctransformers.__version__}")
LangChain: Connecting Language Models to Data Sources
LangChain simplifies the process of connecting language models to various data sources. It provides abstractions for document loaders, text splitters, and vector stores, enabling seamless integration with external data.
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
# Load and split a document
loader = TextLoader("example.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
# Create embeddings
embeddings = HuggingFaceEmbeddings()
doc_embeddings = embeddings.embed_documents([text.page_content for text in texts])
FAISS: Efficient Similarity Search
FAISS enables fast and memory-efficient similarity search and clustering of dense vectors. It's particularly useful for finding similar documents or answering queries based on semantic similarity.
import numpy as np
import faiss
# Create a sample dataset
dimension = 128
nb_vectors = 10000
vectors = np.random.random((nb_vectors, dimension)).astype('float32')
# Build a FAISS index
index = faiss.IndexFlatL2(dimension)
index.add(vectors)
# Perform a similarity search
k = 5 # Number of nearest neighbors to retrieve
query = np.random.random((1, dimension)).astype('float32')
distances, indices = index.search(query, k)
print(f"Indices of {k} nearest neighbors: {indices}")
print(f"Distances to {k} nearest neighbors: {distances}")
CTransformers: High-Performance Inference
CTransformers provides Python bindings for Transformer models implemented in C/C++, offering faster inference compared to pure Python implementations. It's particularly useful for deploying models on edge devices or in resource-constrained environments.
from ctransformers import AutoModelForCausalLM
# Load a pre-trained model
model = AutoModelForCausalLM.from_pretrained("TheBloke/Llama-2-7B-Chat-GGML", model_file="llama-2-7b-chat.ggmlv3.q4_0.bin")
# Generate text
prompt = "Explain the concept of quantum entanglement:"
generated_text = model(prompt, max_new_tokens=50)
print(generated_text)
Combining LangChain and FAISS for Document Retrieval
LangChain can be integrated with FAISS to create powerful document retrieval systems. This combination allows for efficient storage and retrieval of document embeddings.
from langchain.vectorstores import FAISS
from langchain.embeddings import HuggingFaceEmbeddings
# Assuming 'texts' is a list of document chunks
embeddings = HuggingFaceEmbeddings()
vectorstore = FAISS.from_texts([text.page_content for text in texts], embeddings)
# Perform a similarity search
query = "What is machine learning?"
docs = vectorstore.similarity_search(query, k=3)
for doc in docs:
print(f"Relevant text: {doc.page_content[:100]}...")
LangChain Chains: Composing Language Model Applications
LangChain provides a powerful abstraction called "Chains" that allows you to compose complex language model applications by chaining together different components.
from langchain.llms import OpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
llm = OpenAI(temperature=0.7)
prompt = PromptTemplate(
input_variables=["topic"],
template="Write a short blog post about {topic}."
)
chain = LLMChain(llm=llm, prompt=prompt)
result = chain.run("artificial intelligence")
print(result)
FAISS Indexing Techniques
FAISS offers various indexing techniques for different use cases and dataset sizes. Here's an example of using the IVF (Inverted File) index for faster search on large datasets.
import numpy as np
import faiss
dimension = 128
nb_vectors = 1000000
vectors = np.random.random((nb_vectors, dimension)).astype('float32')
# Create an IVF index
nlist = 100 # Number of clusters
quantizer = faiss.IndexFlatL2(dimension)
index = faiss.IndexIVFFlat(quantizer, dimension, nlist)
# Train and add vectors
index.train(vectors)
index.add(vectors)
# Perform a search
k = 5
query = np.random.random((1, dimension)).astype('float32')
distances, indices = index.search(query, k)
print(f"Indices of {k} nearest neighbors: {indices}")
print(f"Distances to {k} nearest neighbors: {distances}")
CTransformers: Model Quantization
CTransformers supports quantized models, which can significantly reduce memory usage and inference time while maintaining reasonable accuracy.
from ctransformers import AutoModelForCausalLM
# Load a quantized model
model = AutoModelForCausalLM.from_pretrained(
"TheBloke/Llama-2-7B-Chat-GGML",
model_file="llama-2-7b-chat.ggmlv3.q4_0.bin", # 4-bit quantized model
model_type="llama"
)
# Generate text
prompt = "Explain the benefits of model quantization:"
generated_text = model(prompt, max_new_tokens=50)
print(generated_text)
LangChain Agents: Autonomous Task Completion
LangChain Agents combine language models with tools to create autonomous systems that can complete complex tasks. Here's an example of a simple agent that can perform web searches and basic calculations.
from langchain.agents import initialize_agent, Tool
from langchain.llms import OpenAI
from langchain.utilities import SerpAPIWrapper, PythonREPL
llm = OpenAI(temperature=0)
search = SerpAPIWrapper()
python_repl = PythonREPL()
tools = [
Tool(
name="Search",
func=search.run,
description="Useful for when you need to answer questions about current events."
),
Tool(
name="Python REPL",
func=python_repl.run,
description="Useful for when you need to run Python code to solve math problems."
)
]
agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)
result = agent.run("What is the population of France divided by 2?")
print(result)
FAISS: Multi-GPU Support
FAISS supports multi-GPU operations for even faster similarity search on large datasets. Here's an example of using multiple GPUs with FAISS.
import numpy as np
import faiss
dimension = 128
nb_vectors = 10000000
vectors = np.random.random((nb_vectors, dimension)).astype('float32')
# Create a multi-GPU index
ngpus = faiss.get_num_gpus()
cpu_index = faiss.IndexFlatL2(dimension)
gpu_index = faiss.index_cpu_to_all_gpus(cpu_index)
# Add vectors to the index
gpu_index.add(vectors)
# Perform a search
k = 5
query = np.random.random((1, dimension)).astype('float32')
distances, indices = gpu_index.search(query, k)
print(f"Indices of {k} nearest neighbors: {indices}")
print(f"Distances to {k} nearest neighbors: {distances}")
CTransformers: Custom Model Loading
CTransformers allows loading custom GGML models, enabling the use of specialized or fine-tuned models for specific tasks.
from ctransformers import AutoModelForCausalLM
# Load a custom GGML model
model = AutoModelForCausalLM.from_pretrained(
"path/to/custom/model",
model_file="custom_model.bin",
model_type="gpt2" # Specify the model architecture
)
# Generate text using the custom model
prompt = "Generate a haiku about artificial intelligence:"
generated_text = model(prompt, max_new_tokens=30)
print(generated_text)
Real-Life Example: Document Question Answering System
This example demonstrates how to create a document question answering system using LangChain, FAISS, and CTransformers.
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from ctransformers import AutoModelForCausalLM
# Load and process documents
loader = TextLoader("large_document.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
# Create embeddings and vector store
embeddings = HuggingFaceEmbeddings()
vectorstore = FAISS.from_documents(texts, embeddings)
# Load language model
model = AutoModelForCausalLM.from_pretrained("TheBloke/Llama-2-7B-Chat-GGML", model_file="llama-2-7b-chat.ggmlv3.q4_0.bin")
# Function to answer questions
def answer_question(question):
# Retrieve relevant documents
docs = vectorstore.similarity_search(question, k=3)
context = " ".join([doc.page_content for doc in docs])
# Generate answer using the language model
prompt = f"Context: {context}\n\nQuestion: {question}\n\nAnswer:"
answer = model(prompt, max_new_tokens=100)
return answer
# Example usage
question = "What are the main challenges in renewable energy adoption?"
print(answer_question(question))
Real-Life Example: Semantic Image Search
This example shows how to create a semantic image search system using FAISS and a pre-trained image embedding model.
import numpy as np
import faiss
from PIL import Image
from torchvision.models import resnet50, ResNet50_Weights
from torchvision.transforms import Compose, Resize, ToTensor, Normalize
# Load pre-trained ResNet model
model = resnet50(weights=ResNet50_Weights.DEFAULT)
model = model.eval()
# Prepare image transformation pipeline
preprocess = Compose([
Resize((224, 224)),
ToTensor(),
Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# Function to extract image features
def extract_features(image_path):
image = Image.open(image_path).convert('RGB')
input_tensor = preprocess(image).unsqueeze(0)
with torch.no_grad():
features = model(input_tensor)
return features.numpy().flatten()
# Index images (assuming we have a list of image paths)
image_paths = ["image1.jpg", "image2.jpg", "image3.jpg", ...]
features = np.array([extract_features(path) for path in image_paths])
# Create FAISS index
dimension = features.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(features)
# Perform semantic search
query_image_path = "query_image.jpg"
query_features = extract_features(query_image_path)
k = 5 # Number of similar images to retrieve
distances, indices = index.search(query_features.reshape(1, -1), k)
print(f"Top {k} similar images:")
for i, idx in enumerate(indices[0]):
print(f"{i+1}. {image_paths[idx]} (distance: {distances[0][i]:.2f})")
Additional Resources
For those interested in diving deeper into LangChain, FAISS, and CTransformers, here are some valuable resources:
- LangChain Documentation: https://python.langchain.com/
- FAISS GitHub Repository: https://github.com/facebookresearch/faiss
- CTransformers GitHub Repository: https://github.com/marella/ctransformers
For academic papers related to these topics:
- "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks" (ArXiv:2005.11401): https://arxiv.org/abs/2005.11401
- "Billion-scale similarity search with GPUs" (ArXiv:1702.08734): https://arxiv.org/abs/1702.08734
- "LoRA: Low-Rank Adaptation of Large Language Models" (ArXiv:2106.09685): https://arxiv.org/abs/2106.09685
These resources provide in-depth information on the concepts, implementations, and applications of the technologies discussed in this presentation.