xbe.at

LLMs and generative AI / Agents and LangChain

Leveraging LangChain, FAISS, and CTransformers in Python:

7 min read, 14 sections

Contents
  1. Introduction to LangChain, FAISS, and CTransformers
  2. LangChain: Connecting Language Models to Data Sources
  3. FAISS: Efficient Similarity Search
  4. CTransformers: High-Performance Inference
  5. Combining LangChain and FAISS for Document Retrieval
  6. LangChain Chains: Composing Language Model Applications
  7. FAISS Indexing Techniques
  8. CTransformers: Model Quantization
  9. LangChain Agents: Autonomous Task Completion
  10. FAISS: Multi-GPU Support
  11. CTransformers: Custom Model Loading
  12. Real-Life Example: Document Question Answering System
  13. Real-Life Example: Semantic Image Search
  14. 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:

  1. LangChain Documentation: https://python.langchain.com/
  2. FAISS GitHub Repository: https://github.com/facebookresearch/faiss
  3. CTransformers GitHub Repository: https://github.com/marella/ctransformers

For academic papers related to these topics:

  1. "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks" (ArXiv:2005.11401): https://arxiv.org/abs/2005.11401
  2. "Billion-scale similarity search with GPUs" (ArXiv:1702.08734): https://arxiv.org/abs/1702.08734
  3. "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.

More in Agents and LangChain

  1. Leveraging LLMs for Unlabeled Data Categorization10 min

    Zero-shot learning enables classification of unlabeled data without prior training by leveraging pre-trained language models through carefully crafted...

  2. Leveraging Graph-Based Knowledge for Informed Retrieval-Augmented Generation9 min

    Graph RAG extends traditional retrieval-augmented generation by incorporating graph-based knowledge representations. This architecture enables contextual...

  3. LLM Multi-Agent Architecture in Python10 min

    Large Language Models (LLMs) have revolutionized natural language processing. Multi-agent architectures leverage multiple LLMs to solve complex tasks...

  4. Leveraging Graph Structures to Enhance LLM Performance with GraphRAG7 min

    GraphRAG is an advanced approach to Retrieval-Augmented Generation (RAG) that leverages graph structures to enhance the performance of Large Language Models...

  5. Swarm OpenAI's Multi-Agent Orchestration Framework13 min

    Swarm architecture implements a foundational multi-agent system where agents operate as independent entities with specialized roles. The base Agent class...

  6. Integrating YOLO OCR and AI Agents for Document Organization29 min

    The YOLO (You Only Look Once) architecture revolutionizes document detection by treating it as a regression problem, directly predicting bounding boxes and...