AI Chat PDF dengan Google PaLM Model

Hendra Permana
3 min readOct 31, 2023

--

Membuat aplikasi Chat dengan PDF adalah implementasi paling sederhana dalam memanfaatkan LLM model sebagai dasar pengembangan aplikasi berbasis AI. Seperti membuat projectHello World ketika kita mempelajari bahasa pemrograman tertentu.

Pada blog post kali ini kita akan membuat aplikasi “Chat dengan PDF” sederhana menggunakan library Langchain pada Python dan PaLM yang dikembangkan oleh Google sebagai LLM Model dan Model Embedding nya.

Environment

Buat project Python bari lalu pastikan library berikut sudah terpasang pada virtual environment:

langchain==0.0.326
PyPDF2==3.0.1
python-dotenv==1.0.0
streamlit~=1.28.0
faiss-cpu==1.7.4
tiktoken==0.5.1
google-generativeai==0.2.2

Buat API KEY baru pada Google Makersuite di laman berikut: https://makersuite.google.com/app/apikey

Buat file .env lalu simpan API KEY tadi pada file .env dengan key:

GOOGLE_API_KEY=<your-api-key-here>

Pada main.py import library yang akan kita gunakan nanti:

import os
import streamlit
from PyPDF2 import PdfReader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from dotenv import load_dotenv
from langchain.vectorstores import FAISS
from langchain.chains.question_answering import load_qa_chain
import google.generativeai as palm
from langchain.embeddings import GooglePalmEmbeddings
from langchain.llms import GooglePalm

Selanjutnya konfigurasi Google PaLM dengan API KEY yang sudah dibuat tadi:


load_dotenv()
api_key = os.getenv("GOOGLE_API_KEY")

palm.configure(api_key=api_key)

Upload File PDF

Oke, kita akan membuatnya sangat sederhana. Kita gunakan Streamlit sebagai UI framework dan Web Servernya.

Buat main function lalu buat Header

def main():
streamlit.header("Basic Chat With PDF")

tambahkan field file upload dan hanya accept file PDF untuk nanti kita lakukan ekstraksi kontennya

pdf = streamlit.file_uploader("Upload a PDF File", type='pdf')

Ekstraksi Teks dari PDF

Oke, kita ekstrak konten dari PDF yang telah diupload, lalu simpan semua teks pada sebuah variable

    if pdf is not None:
pdf_reader = PdfReader(pdf)

text = ""
for page in pdf_reader.pages:
text += page.extract_text()

Split Teks menjadi Chuncks

Teks yang diekstrak dari file PDF kemudian dibagi menjadi “chunks” atau potongan-potongan teks yang lebih kecil. Tujuannya untuk memudahkan proses sehingga menjadi lebih efisien, karena LLM mempunyai Windows Context yang terbatas.

        text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
length_function=len
)

# Split the text into chunks
chunks = text_splitter.split_text(text=text)

Embedding

Chunks yang sudah dibuat tadi (yang berisi bagian-bagian teks didalamnya) perlu kita ubah menjadi Vector. Pada proses ini kita menggunakan model embedding-gecko-001 yang disediakan oleh PaLM. Lalu, kita muat dalam struktur data Vector Store menggunakan librari FAISS nya Meta untuk selanjutnya dilakukan pemuatan dan penyimpanan teks yang di embed dalam format vector tadi, sehingga memiliki semantic index yang dibutuhkan pada proses berikutnya.

        # Generate a store name from the PDF file name
store_name = pdf.name[:-4]
streamlit.write(store_name)

# Initialize Google Palm embeddings
embeddings = GooglePalmEmbeddings(model_name="models/embedding-gecko-001")
# Attempt to load the vector store from local storage, or create a new one if it doesn't exist
try:
vector_store = FAISS.load_local(store_name, embeddings)
except RuntimeError:
vector_store = FAISS.from_texts(chunks, embedding=embeddings)
vector_store.save_local(store_name)

Similarity Search

Proses Embedding tadi mungkin memerlukan waktu tergantung besarnya file PDF yang di upload. Selanjutnya kita tambahkan Text Input untuk user melakukan query atau menuliskan perintah/prompt

query = streamlit.text_input("Ask questions about your PDF file:")

Secara garis besar aplikasi akan memproses input pengguna dan mencari dokumen teks yang paling mirip dengan input, lalu menyajikannya dalam jawaban yang lebih “rasional” dengan LLM Model.

Pertama, lakukan Similiraty Search berdasarkan prompt pada Vector Store .

        if query:
# Perform similarity search
docs = vector_store.similarity_search(query=query, k=3)

Lalu dengan menggunakan model text-bison-001 dari PaLM, kita lakukan chaining antara hasil Similiraty Search dan input dari user dengan tipe chain QA (Question Answer) untuk menampilkan hasil yang staright-forward.

llm = GooglePalm(model_name="models/text-bison-001")
chain = load_qa_chain(llm=llm, chain_type="stuff")
response = chain.run(input_documents=docs, question=query)

Tampilkan Hasil

Proses ini juga membutuhkan beberapa waktu. Terakhir, tampilkan result ke UI, maka hasilnya adalah seperti berikut:

Generative Result

Source Code

--

--

No responses yet