<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arun Venkataswamy</title>
    <description>The latest articles on DEV Community by Arun Venkataswamy (@arun_venkataswamy).</description>
    <link>https://dev.to/arun_venkataswamy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1679360%2Fba404864-deb4-4251-94db-b37aecfa2903.jpeg</url>
      <title>DEV Community: Arun Venkataswamy</title>
      <link>https://dev.to/arun_venkataswamy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arun_venkataswamy"/>
    <language>en</language>
    <item>
      <title>Exploring the Extractive Capabilities of Large Language Models – Beyond Generation and Copilots</title>
      <dc:creator>Arun Venkataswamy</dc:creator>
      <pubDate>Tue, 16 Jul 2024 16:29:57 +0000</pubDate>
      <link>https://dev.to/arun_venkataswamy/exploring-the-extractive-capabilities-of-large-language-models-beyond-generation-and-copilots-1i7h</link>
      <guid>https://dev.to/arun_venkataswamy/exploring-the-extractive-capabilities-of-large-language-models-beyond-generation-and-copilots-1i7h</guid>
      <description>&lt;p&gt;We have all seen the power of Large Language Models in the form of a GPT-based personal assistant from OpenAI called &lt;a href="https://chatgpt.com/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt;. You can ask questions about the world, ask for recipes, or ask it to generate a poem about a person. We have all been awestruck by the capabilities of this personal assistant.&lt;/p&gt;

&lt;p&gt;Unlike many other personal assistants, this is not a toy. It has significant capabilities which can increase your productivity. You can ask it to write a marketing copy or Python script for work. You can ask it to provide a detailed itinerary for a weekend getaway.&lt;/p&gt;

&lt;p&gt;This is powered by Large Language Models (LLMs) using a technology called Generative Pre-trained Transformer (GPT). LLMs are a subset of a broader category of AI models known as neural networks, which are systems inspired by the human brain. It all started with the pivotal paper “&lt;a href="https://research.google/pubs/attention-is-all-you-need/" rel="noopener noreferrer"&gt;Attention is all you need&lt;/a&gt;” released by Google in 2017.&lt;/p&gt;

&lt;p&gt;Since then, brilliant scientists and engineers have created and mastered the transformer model which has created groundbreaking changes that are disrupting the status quo in things ranging from creative writing, language translation, image generation, and software coding to personalized education.&lt;/p&gt;

&lt;p&gt;This technology harnesses the patterns in the vast quantities of text data they have been trained with to predict and generate outputs. Till now, this path-breaking technology has been used by enterprises primarily in these areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Personal assistants&lt;/li&gt;
&lt;li&gt;Chatbots&lt;/li&gt;
&lt;li&gt;Content generation (marketing copies, blogs, etc)&lt;/li&gt;
&lt;li&gt;Question answering over documents (RAG)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the main capabilities of these LLMs is their ability to reason within a given context. We do not know if they reason the way we humans reason, but they do show some emergent behaviour that has the capacity to somehow do it, given the right prompts to do so. This might not match humans, but it is good enough to extract information from a given context. This extraction capability powers the question-answering use case of LLMs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structured data from unstructured sources
&lt;/h2&gt;

&lt;p&gt;Multiple analysts estimate that up to 80% of the data available with enterprises exist in an unstructured form. That is information stored in text documents, video, audio, social media, server logs etc. It is a known fact that if enterprises can extract information from these unstructured sources it would give them a huge comparative advantage.&lt;/p&gt;

&lt;p&gt;Unfortunately, today if we have to extract information from these unstructured sources, we need humans to do it and it is costly, slow, and error-prone. We could write applications to extract information, but that would be a very difficult and expensive project and in some cases impossible. Given the ability of LLMs to “see” patterns in text and do some form of “pseudo reasoning”, they would be a good choice to extract information from these vast troves of unstructured data in the form of PDFs and other document files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining our use case
&lt;/h2&gt;

&lt;p&gt;For the sake of this discussion, let us define our typical use cases. These are actual real-world use cases many of our customers have. Note that some of the customers need information extracted from tens of thousands of these types of documents every month.&lt;/p&gt;

&lt;p&gt;Information extracted could be simple ones like personal data (name, email address, address) and complex ones like line items (details of each product/service item in the invoice, details of all companies in prior employment in resumes etc)&lt;/p&gt;

&lt;p&gt;Most of these documents have between 1 and 20 pages and they fit into the context size of OpenAI’s GPT4 Turbo and Google’s Gemini Pro LLMs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Information extraction from Invoices.&lt;/li&gt;
&lt;li&gt;Information extraction from Resumes.&lt;/li&gt;
&lt;li&gt;Information extraction from Purchase orders.&lt;/li&gt;
&lt;li&gt;Information extraction from Medical bills.&lt;/li&gt;
&lt;li&gt;Information extraction from Insurance documents.&lt;/li&gt;
&lt;li&gt;Information extraction from Bank and Credit card statements.&lt;/li&gt;
&lt;li&gt;Information extraction from SaaS contracts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Traditional RAG is an overkill for many use cases
&lt;/h2&gt;

&lt;p&gt;Retrieval-Augmented Generation is a technique used in natural language processing that combines the capabilities of a pre-trained language model with information retrieval to enhance the generation of text. This method leverages the strengths of two different types of models: a language model and a document retrieval system. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RAG is typically used in a question-answering scenario. When we have a bunch of documents or one large document and we want to answer a specific question. We would use RAG techniques to:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Determine which document contains the information&lt;/li&gt;
&lt;li&gt;Determine which part of the document contains the information&lt;/li&gt;
&lt;li&gt;Send this part of the document as a context along with the question to an LLM and get an answer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The above steps are for the simplest of RAG use cases. Libraries like Llamaindex and Langchain provide the tools to deploy a RAG solution. And they have workflows for more complex and smarter RAG implementations. &lt;/p&gt;

&lt;p&gt;RAGs are very useful to implement smart chatbots and allow employees or customers of enterprises to interact with vast amounts of information. RAGs can be used for information extraction too, but it would be an overkill for many use cases. Sometimes it could become expensive to do so too.&lt;/p&gt;

&lt;p&gt;We deal with some customers who need information extracted from tens of thousands of documents every month. And the information extracted is not for human consumption. The information goes straight into a database or to other downstream automated services. Here is where a simple prompt based extraction could be way more efficient than traditional RAG. Both from a cost perspective and computational complexity perspective.  More information in the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompt-based data extraction
&lt;/h2&gt;

&lt;p&gt;The context windows of LLMs are increasing and the cost of LLM services are coming down. We can comfortably extrapolate this and conclude that this trend will continue into the near future. We can make use of this and use direct prompting techniques to extract information from documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source document&lt;/strong&gt;&lt;br&gt;
Let’s take a couple of restaurant invoices as the source documents to explore the extraction process. An enterprise might encounter hundreds of these documents in claims processing. Also, note that these two documents are completely different in their form and layouts. Traditional machine learning and intelligent document processing (IDP) tools will not be able to parse both documents using the same learning or setups. The true power of LLMs is their ability to understand the context through language. We will see how LLMs are capable of extracting information from these documents using the same prompts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyywc50tg9f2mqer6bhot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyywc50tg9f2mqer6bhot.png" alt="poor-photo" width="800" height="1522"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Document #1 - Photo of printed restaurant invoice&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxxilcodet4re82srw88.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxxilcodet4re82srw88.png" alt="Invoice" width="800" height="1288"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Document #2 - PDF of restaurant invoice&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional machine learning and intelligent document processing (IDP) will not be able to parse different documents using the same learning or setups.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preprocessing&lt;/strong&gt;&lt;br&gt;
LLMs required pure text as inputs. This means that all documents need to be converted to plain text. The weakest link in setting up an LLM-based toolchain to do extraction is the conversion of the original document into a pure text document which LLMs can consume as input.&lt;/p&gt;

&lt;p&gt;Most documents available in enterprises are in PDF format. PDFs can contain text or their pages can be made of scanned documents that exist as images inside the document. Even if information is stored as text inside PDFs, extracting them is no simple task. PDFs were not designed as a text store. They contain layout information that can reproduce the “document” for printing or visual purposes. The text inside the PDFs can be broken and split at random places. They do not always follow a logical order. But they contain layout information which will be used by the PDF rendering software which will make it look as if the text is coherent to a human eye.&lt;/p&gt;

&lt;p&gt;For example, the simple text “Hello world, welcome to PDFs” could be split up as “Hello”, “world, wel ”, “come”, “to” and “PDFs”. And the order can be mixed up too. But precise location information would be available for the rendering software to reassemble the text visually.&lt;/p&gt;

&lt;p&gt;The PDF-to-text converter has to consider the layout information and try to reconstruct the text as intended by the author and make grammatical sense. In the case of scanned PDF documents, the information inside is in the form of images and we need to use an OCR to extract the text from the PDF&lt;/p&gt;

&lt;p&gt;The following texts are extracted from the documents mentioned above using Unstract’s &lt;a href="https://unstract.com/llmwhisperer/" rel="noopener noreferrer"&gt;LLM Whisperer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data extracted from Document #1&lt;br&gt;
From the photo of the physical restaurant invoice&lt;br&gt;
&lt;a href="https://pg.llmwhisperer.unstract.com/" rel="noopener noreferrer"&gt;Extracted with LLMWhisperer&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffn9ywpgjzsmfk3j47jwv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffn9ywpgjzsmfk3j47jwv.png" alt="extracted-text" width="800" height="860"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data extracted from Document #2&lt;br&gt;
PDF of restaurant invoice&lt;br&gt;
&lt;a href="https://pg.llmwhisperer.unstract.com/" rel="noopener noreferrer"&gt;Extracted with LLMWhisperer&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flkymvbbj2gxw6dk3l15q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flkymvbbj2gxw6dk3l15q.png" alt="extracted-text2" width="800" height="1069"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Extraction prompt engineering
&lt;/h2&gt;

&lt;p&gt;Constructing an extraction prompt for a LLM is an iterative process in general. We will keep tweaking the prompt till we are able to extract the information you require. In the case of generalised extraction – when the same prompt has to work over multiple different documents more care might be taken by experimenting with a sample set of documents. When I say “multiple different documents” I mean different documents with the same central context. Take for example the two documents we consider in this article. Both are restaurant invoices but their form and layouts are completely different. But their context is the same. They are restaurant invoices.&lt;/p&gt;

&lt;p&gt;The following prompt structure is what we use while dealing with relatively big LLMs like GPT3.5, GPT4 and Gemini Pro:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Preamble&lt;/li&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;Grammar&lt;/li&gt;
&lt;li&gt;Task&lt;/li&gt;
&lt;li&gt;Postamble&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A &lt;strong&gt;preamble&lt;/strong&gt; is the text we prepend to every prompt. A typical preamble would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your ability to extract and summarise this restaurant invoice accurately is essential for effective analysis. Pay close attention to the context's language, structure, and any cross-references to ensure a comprehensive and precise extraction of information. Do not use prior knowledge or information from outside the context to answer the questions. Only use the information provided in the context to answer the questions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Context&lt;/strong&gt; is the text we extracted from PDF or image&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Grammar&lt;/strong&gt; is used when we want to provide synonyms information. Especially for smaller models. For example for the document type we are considering, restaurant invoices – invoice can be “bill” in some countries. For sake of this example, we will ignore grammar information.&lt;/p&gt;

&lt;p&gt;**Task **is the actual prompt or question you want to ask. The crux of the extraction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Postamble&lt;/strong&gt; is text we add to the end of every prompt. A typical postamble would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Do not include any explanation in the reply. Only include the extracted information in the reply.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that Except for the context and task none of the other sections of the prompt is compulsory.&lt;/p&gt;

&lt;p&gt;Let’s put an entire prompt together and see the results. Let’s ignore the grammar bit for now. In this example, our task prompt would be,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Extract the name of the restaurant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The entire prompt to send to the LLM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your ability to extract and summarise this restaurant invoice accurately is essential for effective analysis. Pay close attention to the context's language, structure, and any cross-references to ensure a comprehensive and precise extraction of information. Do not use prior knowledge or information from outside the context to answer the questions. Only use the information provided in the context to answer the questions.

Context:
—-------

          BURGER       SEIGNEUR 

            No. 35, 80 feet road, 
              HAL 3rd Stage, 
           Indiranagar, Bangalore 
         GST: 29AAHFL9534H1ZV 

   Order Number    : T2- 57 

   Type : Table 
   Table   Number:     2 

   Bill   No .: T2 -- 126653 
  Date:2023-05-31   23:16:50 
  Kots: 63 

  Item               Qty    Amt 

  Jack The 
  Ripper           1        400.00 
  Plain Fries + 
  Coke 300 ML      1        130.00 

  Total Qty:        2 
  SubTotal:                 530.00 

  GST@5%                     26.50 
      CGST @2.5%       13.25 
      SGST @2.5%       13.25 

 Round Off :                  0.50 
 Total Invoice   Value:        557 

       PAY    : 557 

 Thank you, visit   again! 

Powered   by - POSIST

-----------
Extract the name of the restaurant.

Your response:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy and paste the above prompt into ChatGPT virtual assistant. Or you may use their APIs directly to complete the prompt. &lt;/p&gt;

&lt;p&gt;The result you get is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The name of the restaurant is Burger Seigneur.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you just need the name of the restaurant and not a verbose answer, you can play around with the postamble or the task definition itself. Let’s change the task to be more specific:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Extract the name of the restaurant. Reply with just the name.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The result you get now is:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BURGER SEIGNEUR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you construct a similar prompt for document #2, you will get the following result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CHAI KINGS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Here is a list of task prompts and their results&lt;/strong&gt;&lt;br&gt;
Please note that if you use the same prompts in ChatGPT, the results can be a bit more verbose. These results are from the Azure OpenAI with GPT4 turbo model accessed through their API. You can always tweak the prompts to get the desired outputs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task Prompt 1
Extract the name of the restaurant
Document 1 response
BURGER SEIGNEUR
Document 2 response
Chai Kings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task Prompt 2
Extract the date of the invoice
Document 1 response
2023-05-31
Document 2 response
07 March 2024
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task Prompt 3
Extract the customer name if it is present. Else return null
Document 1 response
NULL
Document 2 response
Arun Venkataswamy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task Prompt 4
Extract the address of the restaurant in the following JSON format:
{
    "address": "",
    "city": "" 
}
Document 1 response
{ 
    "address": "No. 35, 80 feet road, HAL 3rd Stage, Indiranagar",
    "city": "Bangalore" 
}
Document 2 response
{
    "address": "Old Door 28, New 10, Kader Nawaz Khan Road, Thousand Lights",
    "city": "Chennai"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task Prompt 5
What is the total value of the invoice
Document 1 response
557
Document 2 response
₹196.84
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task Prompt 6
Extract the line items in the invoice in the following JSON format:
[
    {
        "item": "",
        "quantity": 0,
        "total_price": 0
    }
]
Document 1 response
[
    {
        "item": "Jack The Ripper",
        "quantity": 1,
        "total_price": 400
    },
    {
        "item": "Plain Fries + Coke 300 ML",
        "quantity": 1,
        "total_price": 130
    }
]
Document 2 response
[
    {
        "item": "Bun Butter Jam",
        "quantity": 1,
        "total_price": 50
    },
    {
        "item": "Masala Pori",
        "quantity": 2,
        "total_price": 50
    },
    {
        "item": "Ginger Chai",
        "quantity": 1,
        "total_price": 158
     }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see from the above, LLMs are pretty smart with their ability to extract information from a given context. A single prompt works across multiple documents with different forms and layouts. This is a huge step up from traditional machine learning models and methods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post-processing&lt;/strong&gt;&lt;br&gt;
We can extract almost any piece of information from the given context using LLMs. But sometimes, it might require multiple passes with an LLM to get a result that can be directly sent to a downstream application. For example, if the downstream application or database requires a number, we have to convert the result to a number. Take a look at the invoice value extraction prompt in the above table. For document #2 it returns a number with a currency symbol. The LLM returned ₹196.84. So in this case we need to have one more step to convert the extracted information to an acceptable format. This can be done in two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Programmatically: We can programmatically convert the result into a number format. But this would be a difficult task since the formatting could include hundreds separators too. For example $1,456.34. This needs to be converted to 1456.34. Similarly, the hundreds separator could be different for different locales. Example €1.456,34. &lt;/li&gt;
&lt;li&gt;With LLMs: Using LLMs to convert the result into the format we require could be much easier. Since the full context is not required, the cost involved will also be relatively much smaller compared to the actual extraction itself. We can create a prompt like this: "Convert the following to a number which can be directly stored in the database: $1,456.34. Answer with just the number. No explanations required“. Will produce the output: 1456.34&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Similar to numbers, we might have to post the process results for dates and boolean values too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Unstract and LLMWhisperer
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://unstract.com/" rel="noopener noreferrer"&gt;Unstract&lt;/a&gt; is a no-code platform to eliminate manual processes involving unstructured data using the power of LLMs. The entire process discussed above can be set up without writing a single line of code. And that’s only the beginning. The extraction you set up can be deployed in one click as an API or ETL pipeline.&lt;/p&gt;

&lt;p&gt;With API deployments you can expose an API to which you send a PDF or an image and get back structured data in JSON format. Or with an ETL deployment, you can just put files into a Google Drive, Amazon S3 bucket or choose from a variety of sources and the platform will run extractions and store the extracted data into a database or a warehouse like Snowflake automatically. Unstract is an Open Source software and is available at &lt;a href="https://github.com/Zipstack/unstract" rel="noopener noreferrer"&gt;https://github.com/Zipstack/unstract&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to quickly try it out, signup for our free trial. More information &lt;a href="https://unstract.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;LLMWhisperer is a &lt;a href="https://unstract.com/llmwhisperer/" rel="noopener noreferrer"&gt;document-to-text converter&lt;/a&gt;. Prep data from complex documents for use in Large Language Models. LLMs are powerful, but their output is as good as the input you provide. Documents can be a mess: widely varying formats and encodings, scans of images, numbered sections, and complex tables. Extracting data from these documents and blindly feeding them to LLMs is not a good recipe for reliable results. LLMWhisperer is a technology that presents data from complex documents to LLMs in a way they’re able to best understand it.&lt;/p&gt;

&lt;p&gt;If you want to quickly take it for test drive, you can checkout our &lt;a href="https://pg.llmwhisperer.unstract.com/" rel="noopener noreferrer"&gt;free playground&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note: I originally posted this on the &lt;a href="https://unstract.com/blog/extractive-capabilities-of-large-language-models/" rel="noopener noreferrer"&gt;Unstract blog&lt;/a&gt; a couple of weeks ago.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>PDF Hell and Practical RAG Applications</title>
      <dc:creator>Arun Venkataswamy</dc:creator>
      <pubDate>Mon, 01 Jul 2024 11:01:34 +0000</pubDate>
      <link>https://dev.to/arun_venkataswamy/pdf-hell-and-practical-rag-applications-api</link>
      <guid>https://dev.to/arun_venkataswamy/pdf-hell-and-practical-rag-applications-api</guid>
      <description>&lt;p&gt;If you have tried to extract text from PDFs you would have come across a myriad of complications related to it. It is relatively easy to do a POC or experiment, but when it comes to handling PDFs from the real world on a consistent basis, it is a tremendously difficult problem to solve. In this blog post, we explore the common but often difficult challenge: &lt;a href="https://unstract.com/"&gt;extracting text from PDFs&lt;/a&gt; for use in RAG, natural language processing, and other applications of large language models (LLMs). While PDFs are a universal and ubiquitous format, valued for their ability to preserve the layout and integrity of content across different platforms, they were not originally designed for easy extraction of the text they contain. This presents a unique set of challenges for developers who need to repurpose content from PDF documents into dynamic, text-based applications.&lt;/p&gt;

&lt;p&gt;Our experience stems from building &lt;a href="https://unstract.com/llmwhisperer/"&gt;LLMWhisperer&lt;/a&gt;, a Text Extraction service that extracts data from images and PDFs, preparing it and optimizing it for consumption by Large Language Models or LLMs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced PDF Text Extractor Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc5mirgw7k20avqjbawls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc5mirgw7k20avqjbawls.png" alt="Advanced PDF Text Extractor Architecture" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is it difficult to extract meaningful text from PDFs?
&lt;/h2&gt;

&lt;p&gt;PDFs are primarily designed to maintain the exact layout and presentation of content across varied devices and platforms. Also ensuring that documents look the same regardless of where they're viewed or printed. This design goal is highly beneficial for document preservation, consistent printing, and sharing fully-formatted documents between users. Another popular use case is PDF forms that can be electronically and portably filled out.&lt;/p&gt;

&lt;p&gt;However, this very strength of the PDF format can become a challenge when extracting text for RAG or natural language processing (NLP) applications. Let’s delve a little deeper into how text is organized in PDFs. Refer to the figure below. Text in a PDF file is organized as text frames or records. It is based on a fixed layout and lacks any logical or semantic structure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbqhqhzvnv70izvt1yh7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbqhqhzvnv70izvt1yh7i.png" alt="A sample PDF file opened in Libreoffice shows how a PDF file is organized" width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: &lt;a href="https://www.libreoffice.org/"&gt;Libreoffice&lt;/a&gt; is a good tool to open PDFs to understand how it is organized. It opens PDF documents in the drawing tool. You can make minor edits but it is not really designed for easy editing of PDFs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fixed Layout
&lt;/h3&gt;

&lt;p&gt;The fixed layout of PDFs is essential for ensuring documents appear identical across different platforms and devices (unlike in say, HTML where text generally adapts to the device’s form factor it’s being displayed on). This fixed layout feature is particularly valuable in contexts like legal documents, invoices, academic papers, and professional publications, where formatting is important. However, for NLP tasks, this fixed layout presents several issues:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-linear Text Flow:&lt;/strong&gt; Text in PDFs might be visually organized in columns, sidebars, or around images. This makes intuitive sense to a human reader navigating the page visually, but when the text is extracted programmatically, the order can come out mixed up. For example, a text extraction tool might read across a two-column format from left to right, resulting in sentences that alternate between columns, completely breaking the text semantically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Position-Based Text:&lt;/strong&gt; Since text placement in PDFs is based on exact coordinates rather than relational structure, extracting text often yields strings of content without the contextual positioning that would inform a reader of headings, paragraph beginnings, or document sections. This spatial arrangement must be programmatically interpreted, which is not always straightforward and often requires advanced processing to deduce the structure from the raw coordinates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lack of Logical Structure
&lt;/h3&gt;

&lt;p&gt;While theoretically the ability exists, in the wild, PDFs most often do not encode the semantic structure of their content. While a visually formatted document might appear to have a clear organization into headings, paragraphs, and sections, this structure is often not explicitly represented in the PDF's internal data hierarchy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visual vs. Semantic Markup:&lt;/strong&gt; Unlike HTML, which uses tags to denote headings, paragraphs, and other content blocks, PDFs typically lack these semantic markers. Text might be larger or in bold to indicate a heading to a human, but without proper tagging, a text extraction tool sees only a string of characters. This makes it difficult to programmatically distinguish between different types of content like titles, main text, or captions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Absence of Standard Structure Tags:&lt;/strong&gt; Although PDF/A (an ISO-standardized version of PDF specialized for archiving and long-term preservation) and tagged PDFs exist, most PDFs in the real world do not take advantage of these enhancements. Tagged PDFs include metadata about document structure, which aids in reflowing text and improving accessibility. Without these tags, automated tools must rely on heuristic methods to infer the document structure, such as analyzing font sizes and styles, indentation, or the relative position on the page.&lt;/p&gt;

&lt;p&gt;To address these challenges in NLP use cases, we might have to write sophisticated and hybrid document analysis tools that combine optical character recognition (OCR) and machine learning models that can learn from large datasets of documents to better predict and reconstruct the logical ordering of text.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools/Libraries for text extraction from text PDFs
&lt;/h3&gt;

&lt;p&gt;A list of popular Python libraries for extracting text from PDFs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/jsvine/pdfplumber"&gt;pdfplumber&lt;/a&gt; (Our favorite, it is based on pdfminer.six)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/PyPDF2/"&gt;PyPDF2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/pdfminer.six/"&gt;pdfminer.six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pymupdf/PyMuPDF"&gt;PyMuPDF&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each library has its own pros and cons. Choosing the right one will be based on what type of PDF documents you are going to process and/or the eventual use of the text extracted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is it even more difficult to extract meaningful text from PDFs?
&lt;/h2&gt;

&lt;p&gt;Many PDFs are not “text” PDFs. They contain scanned or photographed images of pages. In these cases the only option is to either extract the image from the PDF or convert the PDF pages to images and then use an OCR application to extract the text from these images. Then the output from the OCR should be reconstructed as a page of text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8d30ofpgtiq8earg3gky.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8d30ofpgtiq8earg3gky.png" alt="A sample PDF file opened in Libreoffice to show&amp;lt;br&amp;gt;
how a PDF file with scanned contents  is organized" width="800" height="611"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A sample PDF file opened in Libreoffice to show how a PDF file with scanned contents  is organized&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Preprocessing
&lt;/h3&gt;

&lt;p&gt;Many scanned PDFs are not perfect. Scanned images might contain unwanted artifacts which will cause OCR output quality to degrade. If the PDF has a photo of some document page rather than a proper of it — the issues you might face are potentially multiplied. Lighting conditions, rotation, skew, coverage and compression levels of the original photo might lead to even more degradation of OCR output quality.&lt;/p&gt;

&lt;p&gt;Preprocessing is an important step which might need to be taken up before sending the image to OCR. Preprocessing typically involves noise reduction, rescaling, de-rotation, cropping, level adjustments and grayscale conversion. Note that some of the OCR providers have the preprocessing step built in. For example when you use &lt;a href="https://unstract.com/llmwhisperer/"&gt;LLMWhisperer&lt;/a&gt;, preprocessing is done automatically and frees the user from worrying about it.&lt;/p&gt;

&lt;h3&gt;
  
  
  OCR
&lt;/h3&gt;

&lt;p&gt;If you’ve read thus far, you probably already know OCR stands for Optical Character Recognition. It represents a family of technologies that convert images that contain text to machine readable text (generally speaking, conversion of text in images to ASCII or Unicode). It is a technology that is incredibly useful in digitizing printed text or text images leading to the ability of editing, searching and storing the contents of the original document. In the context of this blog post, it helps us extract text from scanned documents or photographed pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools/Libraries for text extraction from scanned/image PDFs
&lt;/h3&gt;

&lt;p&gt;A small list of utilities for extracting text from images. Note that this list shown here is very small subset and there are a lot of tools out there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Locally runnable

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tesseract-ocr/tessdoc"&gt;Tesseract&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/PaddlePaddle/PaddleOCR"&gt;Paddle OCR&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Cloud services

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://azure.microsoft.com/en-in/products/ai-services/ai-document-intelligence"&gt;Azure Document Intelligence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/document-ai?hl=en"&gt;Google Document AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/textract/"&gt;Amazon Textract&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choosing a OCR is based on multiple factors and not the quality of extraction alone. OCR is a continuously evolving technology. Recent improvements in machine learning have made the quality of extraction reach new heights. But unfortunately not everyone has access to high end CPUs and GPUs to run the models. The cloud services from the big three have very high quality OCRs. But if there is a constraint on user privacy and secrecy, the cloud-based services might not be an option for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  And the other woes
&lt;/h2&gt;

&lt;p&gt;Apart from the difficulties created by the actual format itself, functional requirements and the quality of PDFs can add to the complexities of extracting text from them. Samples from the real world can have a bewildering list of issues making it extremely challenging to extract text. Based on our experience developing and running LLMWhisperer, here are some functional and quality issues we commonly see in the wild.&lt;/p&gt;

&lt;h3&gt;
  
  
  Searchable PDFs
&lt;/h3&gt;

&lt;p&gt;This format allows the document to maintain the visual nature of the original scanned image while also including searchable and selectable text thanks to the OCR’d layer. This makes it easy to search for specific words or phrases within the document, which would not be possible with a simple image based PDF. Take a look at the image below. The top is how it appears in a PDF viewer. The bottom image has been adjusted to show the two layers. The gray layer is the original scanned image. The white text is the OCR’d text which has been added to the PDF and hidden behind the original scanned image. This is what is “selectable” when seen in a PDF viewer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftva7mv0grzvt0nk2ef3a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftva7mv0grzvt0nk2ef3a.png" alt="A sample searchable PDF file containing a scanned image layer and&amp;lt;br&amp;gt;
a searchable text layer which has been OCR’d and added." width="800" height="788"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A sample searchable PDF file containing a scanned image layer and&lt;br&gt;
a searchable text layer which has been OCR’d and added.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This searchable feature is very useful when humans are interacting with the document. But when we want to extract the text programmatically it introduces a bunch of difficulties:&lt;/p&gt;

&lt;h4&gt;
  
  
  Detecting whether it is a searchable PDF
&lt;/h4&gt;

&lt;p&gt;We could detect if there is a large image covering the entire page while also looking for text records in the PDF. But this does not work all the time because many PDFs like certificates or fancy brochures have a background image which can be mistaken for a scanned PDF. This is a difficult problem to solve.&lt;/p&gt;

&lt;h4&gt;
  
  
  Quality of the original OCR
&lt;/h4&gt;

&lt;p&gt;Not all OCRs are great. The original OCR used to generate the searchable text might have created a low quality text base. This is not often easy to detect and objectively quantify especially when there is no human in the loop. In these cases, it is better to consider the document as a purely scanned PDF and take the OCR route and use your own OCR for text extraction, hoping yours is better than the one used to generate the original text.&lt;/p&gt;

&lt;h4&gt;
  
  
  Searchable PDFs are for searching and not full-text extraction
&lt;/h4&gt;

&lt;p&gt;The text records which are available in these PDFs are not for extraction use cases. They can be split at random locations. Take a look at the example shown above. Text frames/records “one” and “space-character-to…” are part of the same sentence but are split. When trying to rebuild text for NLP purposes it is difficult to merge them without using complex techniques. Another example is the text “Learning Algorithms” in the figure above. This title text is not only split into two words but since the size of the text is large, the original OCR overlay system has double spaced the characters (to match location of letters) in the result (take a look at the right pane). There are two records – “L e a r n i n g” and “A l g o r i t h m s”. Again a difficult problem to solve to de-double space the characters when we extract text. There is also a mistake in positions. “Algorithms” has backed into “Learning” creating an overlap. Just everyday difficulties extracting text from PDFs!&lt;/p&gt;

&lt;h3&gt;
  
  
  Extracting tables
&lt;/h3&gt;

&lt;p&gt;Unlike HTML or other document formats, PDF is a fixed layout format. This makes it very difficult to semantically understand where a table is and how it is organized. There are many approaches to extracting tables. Some of them try to understand the layout and some of them use computer vision based libraries to detect tables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Popular Python libraries to extract tables:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://camelot-py.readthedocs.io/en/master/"&gt;Camelot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/tabula-py/"&gt;Tabula&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jsvine/pdfplumber"&gt;Pdfplumber&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/pdftables/"&gt;Pdftables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ashima/pdf-table-extract"&gt;Pdf-table-extract&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of the common approaches used are:&lt;/p&gt;

&lt;h4&gt;
  
  
  Rules based extraction
&lt;/h4&gt;

&lt;p&gt;This approach defines a set of rules and tries to identify table data using the rules. The rules can be based on identifiable markers of cells or boundaries, keywords and other similar items. This is effective when the format of the PDF remains consistent. This works very well when all the documents we process are of the same format or variety. Unfortunately in the real world, PDFs come in so many different forms, a simple rule based approach is not very reliable except for certain controlled use cases.&lt;/p&gt;

&lt;h4&gt;
  
  
  Computer vision
&lt;/h4&gt;

&lt;p&gt;This approach uses computer vision models to detect lines that can be used to identify tables. The visual structure is analyzed to differentiate between rows, columns and cells. This can be used for identifying tables where traditional approaches fail. But keep in mind that this involves adding machine learning libraries and models which is going to bloat your application and will require some serious CPU (or GPU) horsepower to keep it quick. While this provides good results in many use cases, many more PDFs in the real world have tables which do not have good visual differentiation (fancy tables with colors used to define cells etc). Also note that this requires converting even text PDFs to images for the CV libraries to work. This can get very resource intensive, especially for longer documents.&lt;/p&gt;

&lt;h4&gt;
  
  
  Machine learning
&lt;/h4&gt;

&lt;p&gt;Machine learning models can be trained to recognize structures and patterns that are typical of tables. Machine learning models can give better results than computer vision-based systems as they understand the context rather than depending only on visual cues. Again, just like computer vision, machine learning also increases the footprint of your application and requires more resources to run. Also, training a model from scratch is a pretty involved process and getting training data might not be an easy task. It is best to depend on ready made table extraction libraries mentioned earlier.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hybrid approach
&lt;/h4&gt;

&lt;p&gt;In the real world, no single approach works for a broad variety of document types. We most likely will have to settle for a combination of techniques to reliably extract tables from PDFs.&lt;/p&gt;

&lt;h4&gt;
  
  
  LLMWhisperer’s approach
&lt;/h4&gt;

&lt;p&gt;We at Unstract, designed &lt;a href="https://unstract.com/llmwhisperer/"&gt;LLMWhisperer&lt;/a&gt; to extract and reproduce the table’s &lt;em&gt;layout&lt;/em&gt; faithfully rather than trying to extract the table’s individual rows and columns while also extracting hints on where each cell is. Most of our customers use the extracted text from PDF to drive LLM/RAG/Search use cases and this approach works great. From our experience, LLMs are able to comprehend tables when layout is preserved. There is no need to bend over backwards to recreate the whole table from the PDF as a HTML table or as a markdown table. LLMs are smart enough to figure out the contents of most tables when the layout of the table is preserved in the output with tabs or spaces separating columns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Page orientation
&lt;/h3&gt;

&lt;p&gt;A PDF file’s pages can be organized in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Portrait mode&lt;/li&gt;
&lt;li&gt;Landscape mode&lt;/li&gt;
&lt;li&gt;Hybrid, portrait and landscape mode&lt;/li&gt;
&lt;li&gt;Scanned pages in landscape mode which are rotated 90°, 180°, 270°&lt;/li&gt;
&lt;li&gt;Scanned pages or photographed pages might be rotated arbitrarily by ±30°&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvpz9qgs4r0q7z29cdci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvpz9qgs4r0q7z29cdci.png" alt="Sample of a scanned PDF which has been rotated while photographing the original" width="800" height="485"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Sample of a scanned PDF which has been rotated while photographing the original&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Trying to extract text from portrait mode or landscape mode is relatively simple. The extraction becomes more difficult when we have a hybrid PDF in which some pages are in portrait mode and some are in landscape mode. If it is a text based PDF, it is relatively easier, but for scanned PDFs we need to detect this change using direct or indirect methods. When dealing with pages that are arbitrarily rotated (especially PDFs created from photographed documents) detection and correction is never easy. We will have to use image processing libraries and probably machine learning to automatically correct such pages before sending them to an OCR.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bad (for extraction) PDF generators
&lt;/h3&gt;

&lt;p&gt;Some PDF generators will consider every element inside the documents as “curves”. Even characters of the language are stored as “curve” representations. This has certain advantages as it can be reproduced in every medium without the requirement of having font information. But it makes it very difficult to extract text from. The only way to extract text from these documents is to convert the pages to images and then use an OCR for extraction. Figuring out that the given PDF has curves instead of text is a step which needs to be performed before attempting to extract.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqd0aljxml07be4tf3y0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqd0aljxml07be4tf3y0g.png" alt="A zoomed-out portion of a PDF file with curves instead of text.&amp;lt;br&amp;gt;
Each character is represented as a Bezier curve" width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi column page layout and fancy layouts
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;A zoomed-out portion of a PDF file with curves instead of text.&lt;br&gt;
Each character is represented as a Bezier curve&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Multi column page layout is very common in scientific publications and documents like invoices. The text is laid out as two columns as shown in the image below. As mentioned earlier, text in PDFs have a fixed layout. This makes it very difficult to semantically extract the text as paragraphs from these types of documents. We need to use heuristics to intelligently extract text in a semantic order from these types of documents. Some text based PDF generators are smart enough to arrange the text records following semantic ordering. But, as always, in the wild, we have to be prepared to encounter badly created PDFs which have absolutely no semantic ordering of text records. When we have scanned documents (with or without searchable content), we have no option but to use intelligent methods to understand multi-column layouts and extract text which makes semantic sense.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzoxdre3ths7gsdvsbl5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzoxdre3ths7gsdvsbl5.png" alt="A two column PDF file.The lines and arrows indicate how text records are organized in a multi column PDF." width="800" height="267"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A two column PDF file.The lines and arrows indicate how text records are organized in a multi column PDF.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the example shown above, text records can be organized in a semantically correct order as shown in the red lines. But in some PDFs (and all OCR’d documents) text records can be organized in a non-semantic order reading left to right over to the next column before moving to the next line. When text is collected this way, the final text will make no sense to downstream pipeline steps. We need smart ways to reorganize such text to make semantic sense.&lt;/p&gt;

&lt;p&gt;Note that the problems described above are also applicable to pages with fancy layouts like invoices, receipts and test reports.&lt;/p&gt;

&lt;h3&gt;
  
  
  Background images and Watermarks
&lt;/h3&gt;

&lt;p&gt;Background images in PDF files can be a problem for both text based PDFs and scanned PDFs. In text based PDFs, the extractor can confuse the background image to be indicating a scanned PDF and switch to an OCR based extraction which will be hundreds of times slower and cost way more. When using such PDFs that feature background images in an OCR based extraction, it can confuse the OCR if it has contrasting colors or patterns. Especially if the background image and text in front of it have little contrast difference. For example black text on top of dark coloured background images. Human eyes can easily pick it up but for many OCR systems it is a challenge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqjlpv1fhf14my0taw1ze.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqjlpv1fhf14my0taw1ze.png" alt="Sample PDF with a strong watermark which can interfere with text extraction" width="800" height="418"&gt;&lt;/a&gt;&lt;br&gt;
_Sample PDF with a strong watermark which can interfere with text extraction&lt;/p&gt;

&lt;p&gt;Some background images are watermarks and these watermarks can be text. When using OCR for extraction, these watermark texts can get added into the main body of texts. This is also the case for fancy backgrounds containing text in certificates etc.&lt;/p&gt;

&lt;p&gt;In some cases, while using OCR for extracting text (which is the only way for scanned PDFs) background images with text can completely ruin text extraction, making it unextractable without human intervention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hand written forms
&lt;/h3&gt;

&lt;p&gt;PDFs with hand written text are scanned document PDFs. These are typically forms or documents with handwritten notes and then scanned. Not all OCRs are capable of handwriting recognition. Also, OCRs capable of recognising handwritten text might be prohibitively expensive, especially when processing larger volumes.&lt;/p&gt;

&lt;h3&gt;
  
  
  PDFs with form elements like checkboxes and radiobuttons
&lt;/h3&gt;

&lt;p&gt;A PDF form is a document that includes interactive fields where users can enter information. PDF forms can contain text fields, checkboxes, radio buttons, drop-down menus, and other interactive elements that allow users to input or select information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnpz5uf6rypw740v6bcom.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnpz5uf6rypw740v6bcom.png" alt="Sample PDF with form elements" width="800" height="540"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Sample PDF with form elements&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Many PDF libraries are not capable of extracting form elements from the PDF. Even less can extract the form elements' contents which the user has filled in. Even if we decide to convert the form into an image for OCR use, there are a couple of issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The PDF to image conversion software or library should understand the form elements. Very few of them support this. PDF.js supports this, but that would sit well in a NodeJS stack. If you are using a Pythonbased stack, your options are not many.&lt;/li&gt;
&lt;li&gt;Not all OCR are capable of understanding form elements like checkboxes and radiobuttons. Your only option might be to train the OCR to recognize and render such elements if you are not willing to use 3rd party web services.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Large scanned PDFs
&lt;/h3&gt;

&lt;p&gt;Scanned PDFs require OCR to extract the contents. OCR by its nature is a compute intensive process and takes time to convert a page into text. When we are dealing with very large documents (&amp;gt; 100 pages) the time to extract all pages can be significant. Apart from time latencies, high quality OCR services also involve a non-trivial cost factor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Low level text extraction library bugs
&lt;/h3&gt;

&lt;p&gt;PDF files are complicated and the sheer variety and generation variations are so many that writing libraries to process them is an inherently difficult task. There will always be some corner cases the authors of the library could have never anticipated. This will lead to runtime errors which need to be handled. And if a significant portion of your target use is affected by this, then there is no option to either write your own extractor to handle these cases or contribute to the library if it is open source.&lt;/p&gt;

&lt;h3&gt;
  
  
  Headers and Footers
&lt;/h3&gt;

&lt;p&gt;Many PDFs have headers and footers. Headers typically contain information about the document and the owner (company name, address etc) and the footer contains copyright information and page numbers etc. These are repeated across all pages. This information is generally not required in most RAG and information extraction use cases. These headers and footers simply add noise to the context when used with LLMs and other machine learning use cases. Though usually not a major issue, a good extraction tool should be able to ignore or even better, remove them from the final extracted text.&lt;/p&gt;

&lt;h3&gt;
  
  
  PDFs with both text and text as images
&lt;/h3&gt;

&lt;p&gt;Some PDFs can have both native text and embedded images that in turn contain text in them. This requires special handling. The simple solution is to send the entire page to an OCR to extract the text. But this method might be expensive for high volume use cases. This can also substantially increase the time latencies of extraction. If cost or time is important, a custom extraction library has to be used in these cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tables spread out horizontally into many pages
&lt;/h3&gt;

&lt;p&gt;This is not a regular use case. But we might encounter PDFs with wide tables which extend into the next page. It is a very difficult problem to solve. Detecting where the table’s horizontal direction extends into is very difficult. The next logical page may contain the following rows instead of the horizontal overflow. In some cases the next logical page may contain the horizontal overflow. These use cases should be considered special cases and custom logic has to be written. It is easier when you know that all documents that will be processed have a similar structure. If that is the case custom extractors can be written. Unfortunately if these types of documents are not specially dealt with, it might be impossible to handle this case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy issues
&lt;/h3&gt;

&lt;p&gt;As discussed above, writing a high quality PDF extraction library is a huge challenge. If you want to use 3rd party services to do extraction, there might be privacy and security issues. You will be sending information to a 3rd party service. If your digital mandate or rules require strict privacy requirements, you will have to use 3rd party services which can provide on-premise services where your data does not leave your network. &lt;a href="https://unstract.com/llmwhisperer/"&gt;LLMWhisperer&lt;/a&gt; service is one of the services that can be run on-premise, protecting your data from leaving your network.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layout Preservation
&lt;/h3&gt;

&lt;p&gt;If the target use case is to use the extracted text with LLMs and RAG applications, preserving the layout of the original PDF document leads to better accuracy. Large Language Models do a good job of extracting complex data, especially repeating sections and line items when the layout of documents is preserved in the extracted text. Most PDF extraction libraries or OCRs do not provide a layout preserving output mode. You will have to build the layout preserving output with the help of positional metadata provided for the text by either the PDF library or the OCR.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a PDF to text convertor architecture would look like
&lt;/h2&gt;

&lt;p&gt;Considering all the cases described above, a block diagram of a high quality PDF to text convertor would look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9qnov5oszm8uhgpwe7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9qnov5oszm8uhgpwe7s.png" alt="Image description" width="800" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Build vs Buy
&lt;/h2&gt;

&lt;p&gt;Building a high quality PDF extractor is a complex and massive exercise. Building your own tool allows for complete control over the functionality and integration with existing systems. However, this approach requires significant investment in time, expertise and ongoing maintenance. On the other hand, purchasing a ready made, pre-built solution can be quicker to deploy and often comes with continuous updates and professional support.The choice ultimately depends on your specific needs, strategic priorities, resources and budgets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing LLMWhisperer
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://unstract.com/llmwhisperer/"&gt;LLMWhisperer&lt;/a&gt; is a general purpose PDF to text converter service from Unstract.&lt;/p&gt;

&lt;p&gt;LLMs are powerful, but their output is as good as the input you provide. LLMWhisperer is a technology that presents data from complex documents (different designs and formats) to LLMs in a way that they can best understand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Layout preserving modes&lt;/strong&gt;
Large Language Models do a good job of extracting complex data, especially repeating sections and line items when the layout of documents is preserved in the extracted text. LLMWhisperer’s Layout Preserving mode lets you realize maximum accuracy from LLMs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto mode switching&lt;/strong&gt;
While processing documents, LLMWhisperer can switch automatically to OCR mode if text mode extraction fails to generate sufficient output. You don’t have to worry about the extraction mode when sending documents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-compaction&lt;/strong&gt;
The more tokens that go to the LLM, the more time it takes to process your prompts and the more expensive it becomes. With LLMWhisperer’s Auto-compaction, tokens that might not add value to the output are compacted—all while preserving layout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pre-processing&lt;/strong&gt;
To get the best of results, you can control how pre-processing of the scanned images is done. Parameters like Median Filter and Gaussian Blur can be influenced via the API, if needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible deployment options&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SaaS&lt;/strong&gt;
High-performance, fully managed SaaS offering. No more dealing with updates, security, or other maintenance tasks – we’ve got you covered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On-Premise&lt;/strong&gt;
We offer a reliable way of deploying LLMwhisperer on your own servers to ensure the security of ultra-sensitive data.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;And much more&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Support for PDFs and the most common image formats&lt;/li&gt;
&lt;li&gt;High-performance cloud for consistently low-latency processing&lt;/li&gt;
&lt;li&gt;Settable page demarcation&lt;/li&gt;
&lt;li&gt;Three output modes: Layout preserving, Text, Text-Dump&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s next? Action items for the curious
&lt;/h2&gt;

&lt;p&gt;If you want to quickly test LLMWhisperer with your own documents, you can &lt;a href="https://pg.llmwhisperer.unstract.com/"&gt;check our free playground&lt;/a&gt;. &lt;br&gt;
Alternatively, you can sign up for our &lt;a href="https://llmwhisperer.unstract.com/products"&gt;free trial&lt;/a&gt; which allows you to process up to 100 pages a day for free.&lt;/p&gt;

&lt;p&gt;Even better, &lt;a href="https://unstract.com/schedule-a-demo/"&gt;schedule a call with us&lt;/a&gt;. We’ll help you understand how Unstract leverages AI to help document processing automation and how it differs from traditional OCR and RPA solutions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Test drive LLMWhisperer with your own documents. No sign up needed!&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9vz0sly6imoa1tt2gw6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9vz0sly6imoa1tt2gw6.png" alt="Test drive LLMWhisperer with your own documents. No sign up needed!" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: I originally posted this on the &lt;a href="https://unstract.com/blog/pdf-hell-and-practical-rag-applications/"&gt;Unstract blog&lt;/a&gt; a couple of weeks ago.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>opensource</category>
      <category>python</category>
    </item>
  </channel>
</rss>
