Get AI summaries of any video or article — Sign up free
Private GPT4All : Chat with PDF with Local & Free LLM using GPT4All, LangChain & HuggingFace thumbnail

Private GPT4All : Chat with PDF with Local & Free LLM using GPT4All, LangChain & HuggingFace

Venelin Valkov·
5 min read

Based on Venelin Valkov's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

GPT4AllJ can be used for local PDF Q&A by pairing it with retrieval (embeddings + vector search) rather than expecting the model to read the PDF directly.

Briefing

Running a local, privacy-friendly “chat with your PDF” pipeline is practical with GPT4All—provided the workflow is built around retrieval (embeddings + vector search) rather than expecting the model to “know” the document. The core setup uses GPT4AllJ (a GPT-J–based model) together with LangChain, HuggingFace sentence-transformer embeddings, and Chroma to index PDF text on disk. In the demo, the PDF is converted to text, split into token-friendly chunks, embedded, stored in a local vector database, and then queried so the model can answer using retrieved passages from the document.

The walkthrough starts by emphasizing GPT4All’s local execution: the model is downloaded to the machine and runs without Internet access or GPU requirements. On an Ubuntu environment, the experiment focuses on performance and correctness using a specific checkpoint: a GPT4AllJ model with a GPT-J backend, labeled “1.3 groovy,” with a 3.5 GB model file. Installation is handled through a notebook environment (Google Colab is used for downloading and running), and the model is loaded from a local path.

To demonstrate the system, the transcript uses a two-page Microsoft annual-report excerpt: one page contains a dividends table (declaration dates and dividend per share), and the other includes a stock performance graph comparing outcomes versus the S&P 500 and NASDAQ. The PDF is processed in two stages. First, it’s converted into images (for inspection), then into extracted text using PyMuPDF (via the PDF loader). The extracted text is wrapped into LangChain documents with metadata indicating page number and source. Because the model has a limited context window (described as roughly a 1000-token limit), the text is further chunked into smaller pieces (around 100–1024 tokens) so relevant sections can be retrieved.

For retrieval, the pipeline uses HuggingFace embeddings via the SentenceTransformers library, downloading the required PyTorch model and tokenizer. Those embeddings are stored in a local Chroma database directory, enabling similarity search over the document chunks. A retrieval-QA chain then connects the GPT4All model to the vector store, returning answers grounded in the most relevant retrieved text.

Results are mixed and largely tied to CPU speed and retrieval quality. For a straightforward question—dividend per share during 2022—the system answers correctly: 62 cents (matching the table). But a second question—an “investment amount” on 6/22—fails. The run also crashes due to RAM exhaustion, and after rerunning, the model produces an incorrect figure (“1 million dollars”), despite the correct value being present in the table. The transcript attributes the slow runtime to CPU inference and notes that GPU acceleration may not work well with the chosen bindings, leaving performance as a key limitation.

Overall, the demo shows that local PDF Q&A with GPT4All is achievable with a standard RAG pattern (extract → chunk → embed → index → retrieve → generate), but accuracy and speed depend heavily on chunking, prompt choice, and hardware constraints.

Cornell Notes

A local “chat with PDF” system can be built using GPT4AllJ plus a retrieval pipeline. The PDF is extracted to text, split into chunks to fit the model’s limited context, embedded with HuggingFace SentenceTransformers, and stored in a local Chroma vector database. A LangChain retrieval-QA chain then feeds the most relevant chunks to GPT4All so answers come from the document rather than model memory. In the demo, a dividends question is answered correctly (62 cents for 2022), but a more complex table-based question returns an incorrect “investment amount,” and the run can crash due to high RAM use. The biggest practical bottleneck is slow CPU inference, with GPU support described as unreliable for the chosen bindings.

How does the system keep answers grounded in the PDF instead of relying on the model’s general knowledge?

It uses retrieval-augmented generation. After extracting PDF text with PyMuPDF, the text is chunked (about 100–1024 tokens). Those chunks are embedded using HuggingFace SentenceTransformers and stored in a local Chroma database. When a question is asked, the retrieval-QA chain selects the most relevant chunk(s) from Chroma and passes them to GPT4AllJ, along with source metadata (page/source) so the answer is based on retrieved document text.

Why is chunking necessary in this setup?

GPT4AllJ has a limited context window (described as roughly a 1000-token limit). The demo splits the extracted text into smaller documents so the relevant parts of the dividends table and the stock performance content can be retrieved and included in the prompt without exceeding token limits. Chunking also affects overlap: the transcript notes that one page’s content ends up distributed across multiple chunks, with some sections appearing in more than one chunk.

What components are used for embeddings and where are they stored?

Embeddings come from HuggingFace via the SentenceTransformers library. The embedding step downloads the required PyTorch model and tokenizer, then converts each text chunk into vectors. Those vectors are stored in a local Chroma database directory (the demo mentions persisting to disk via DB.persist). This enables fast similarity search during question answering.

What evidence of correctness appears in the demo?

For the question “How much is the dividend per share during 2022,” the system returns 62 cents, and the transcript double-checks it against the dividends table (Declaration date 2022 → dividend per share 62 cents). The answer is presented alongside the retrieved source document(s), indicating the retrieval step found the relevant table content.

What went wrong on the second question, and what constraints were involved?

The question about the “investment amount in Microsoft on 6/22” produced an incorrect result (“1 million dollars”). Before that, the runtime crashed due to using all available RAM, forcing a rerun. Even after rerunning (about six minutes), the model still didn’t extract the correct value from the table, despite it being present in the document—suggesting sensitivity to prompt wording, retrieval chunk selection, and resource limits.

Why is performance slow, and what does the transcript suggest about GPU use?

Inference on CPU is described as slow: the dividends query took about five and a half minutes. The transcript suggests GPU acceleration may not work well with the bindings used for GPT4All in this setup, implying that speed improvements may require different bindings or a working GPU path.

Review Questions

  1. If the PDF text were not chunked, what failure mode would you expect given the model’s token limit?
  2. How would you diagnose whether an incorrect answer is caused by retrieval (wrong chunk) versus generation (model misreading the retrieved text)?
  3. What practical steps could reduce RAM usage or runtime in a local RAG pipeline like this one?

Key Points

  1. 1

    GPT4AllJ can be used for local PDF Q&A by pairing it with retrieval (embeddings + vector search) rather than expecting the model to read the PDF directly.

  2. 2

    The pipeline extracts PDF text (PyMuPDF), wraps it as documents with page/source metadata, and then chunks it to fit the model’s context constraints.

  3. 3

    HuggingFace SentenceTransformers generate embeddings for each chunk, and Chroma stores those vectors locally for similarity search.

  4. 4

    A LangChain retrieval-QA chain connects GPT4AllJ to the Chroma retriever so answers are grounded in retrieved document passages.

  5. 5

    In the demo, a straightforward dividends lookup returns the correct value (62 cents for 2022), demonstrating the approach can work when the relevant table content is retrieved.

  6. 6

    A second table-based question returns an incorrect value and the run can crash due to RAM exhaustion, highlighting sensitivity to retrieval quality and hardware limits.

  7. 7

    CPU inference is slow (minutes per query), and GPU acceleration is described as unreliable with the chosen GPT4All bindings.

Highlights

The demo implements a full local RAG loop: extract PDF text → chunk → embed with SentenceTransformers → store in Chroma → retrieve → answer with GPT4AllJ.
A dividends question is answered correctly (62 cents for 2022), showing retrieval can successfully surface the right table rows.
The “investment amount on 6/22” question fails (and the run crashes from RAM pressure), underscoring that chunking and retrieval precision matter.
On CPU, even a simple query takes about 5.5 minutes, and GPU support is described as problematic with the current bindings.

Topics

Mentioned