精讀《利用 GPT 解讀 PDF》

黃子毅發表於2023-04-17

ChatPDF 最近比較火,上傳 PDF 檔案後,即可透過問答的方式讓他幫你總結內容,比如讓它幫你概括核心觀點、詢問問題,或者做觀點判斷。

背後用到了幾個比較時髦的技術,還好有 ChatGPT for YOUR OWN PDF files with LangChain 解釋了背後的原理,我覺得非常精彩,因此記錄下來並做一些思考,希望可以幫到大家。

技術思路概括

由於 GPT 非常強大,只要你把 PDF 文章內容發給他,他就可以解答你對於該文章的任何問題了。-- 全文完。

等等,那麼為什麼要提到 langChain 與 vector dataBase?因為 PDF 文章內容太長了,直接傳給 GPT 很容易超出 Token 限制,就算他允許無限制的 Token 傳輸,可能一個問題可能需要花費 10~100 美元,這個 成本 也是不可接受的。

因此黑魔法來了,下圖擷取自影片 ChatGPT for YOUR OWN PDF files with LangChain

我們一步步解讀:

  1. 找一些庫把 PDF 內容文字提取出來。
  2. 把這些文字拆分成 N 份更小的文字,用 openai 進行文字向量化。
  3. 當使用者提問時,對使用者提問進行向量化,並用數學函式計算與 PDF 已向量化內容的相似程度。
  4. 把最相似的文字傳送給 openai,讓他總結並回答你的問題。

利用 GPT 解讀 PDF 的實現步驟

我把影片裡每一步操作重新介紹一遍,並補上自己的理解。

登入 colab

你可以在本地電腦執行 python 一步步執行,也可以直接登入 colab 這個 python 執行平臺,它提供了很方便的 python 環境,並且可以一步步執行程式碼並儲存,非常適合做研究。

只要你有谷歌賬號就可以使用 colab。

安裝依賴

要執行一堆 gpt 相關函式,需要安裝一些包,雖然本質上都是不斷給 gpt openapi 發 http 請求,但封裝後確實會語義化很多:

!pip install langchain
!pip install openai
!pip install PyPDF2
!pip install faiss-cpu
!pip install tiktoken

其中 tiktoken 包是教程裡沒有的,我執行某處程式碼時被提示缺少這個包,大家可以提前按上。接下來提前引入一些後面需要用到的函式:

from PyPDF2 import PdfReader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import ElasticVectorSearch, pinecone, Weaviate, FAISS

定義 openapi token

為了呼叫 openapi 服務,需要先申請 token,當你申請到 token 後,透過如下方式定義:

import os
os.environ["OPENAI_API_KEY"] = "***"

預設 langchainopenai 都會訪問 python 環境的 os.environ 來尋找 token,所以這裡定義後,接下來就可以直接呼叫服務了。

如果你還沒有 GPT openapi 的賬號,詳見 保姆級註冊教程。(可惜的是中國被牆了,為了學習第一手新鮮知識,你需要自己找 vpn,甚至花錢買國外手機號驗證碼接收服務,雖然過程比較坎坷,但親測可行)。

讀取 PDF 內容

為了方便在 colab 平臺讀取 PDF,你可以先把 PDF 上傳到自己的 Google Drive,它是谷歌推出的個人雲服務,整合了包括 colab 與檔案儲存等所有云服務(PS:微軟類似的服務叫 One Drive,好吧,理論上你用哪個巨頭的服務都行)。

傳上去之後,在 colab 執行如下程式碼,會彈開一個授權網頁,授權後就可以訪問你的 drive 路徑下資源了:

from google.colab import drive
drive.mount('/content/gdrive', force_remount=True)
root_dir = "/content/gdrive/My Drive/"
reader = PdfReader('/content/gdrive/My Drive/2023_GPT4All_Technical_Report.pdf')

我們讀取了 2023_GPT4All_Technical_Report.pdf 報告,這是一個號稱本地可跑對標 GPT4 的服務(測評)。

將 PDF 內容文字化並拆分為多個小 chunk

首先執行如下程式碼讀取 PDF 文字內容:

raw_text = ''
for i, page in enumerate(reader.pages):
  text = page.extract_text()
  if text:
    raw_text += text

接下來要為呼叫 openapi 服務對文字向量化做準備,因為一次呼叫的 token 數量有限制,因此我們需要將一大段文字拆分為若干小文字:

text_splitter = CharacterTextSplitter(
    separator = "\n",
    chunk_size = 1000,
    chunk_overlap = 200,
    length_function = len,
)
texts = text_splitter.split_text(raw_text)

其中 chunk_size=1000 表示一個 chunk 有 1000 個字元,而 chunk_overlap 表示下一個 chunk 會重複上一個 chunk 最後 200 字元的內容,方便給每個 chunk 做銜接,這樣可以讓找相似性的時候儘量多找幾個 chunk,找到更多的上下文。

向量化來了!

最重要的一步,利用 openapi 對之前拆分好的文字 chunk 做向量化:

embeddings = OpenAIEmbeddings()
docsearch = FAISS.from_texts(texts, embeddings)

就是這麼簡單,docsearch 是一個封裝物件,在這一步已經迴圈呼叫了若干次 openapi 介面將文字轉化為非常長的向量。

文字向量化又是一個深水區,可以看下這個 介紹影片,簡單來說就是一把文字轉化為一系列數字,表示 N 維的向量,利用數學計算相似度,可以把文書處理轉化為連續的數字進行數學處理,甚至進行文字加減法(比如 北京-中國+美國=華盛頓)。

總之這一步之後,我們本地就拿到了各段文字與其向量的對應關係,比如 “這是一段文字” 對應的向量為 [-0.231, 0.423, -0.2347831, ...]

利用 chain 生成問答服務

接下來要串起完整流程了,初始化一個 QA chain 表示與 GPT 使用 chat 模型進行問答:

from langchain.chains.question_answering import load_qa_chain
from langchain.llms import OpenAI
chain = load_qa_chain(OpenAI(), chain_type="stuff")

接下來就可以問他 PDF 相關問題了:

query = "who are the main author of the article?"
docs = docsearch.similarity_search(query)
chain.run(input_documents=docs, question=query)
#  The main authors of the article are Yuvanesh Anand, Zach Nussbaum, Brandon Duderstadt, Benjamin Schmidt, and Andriy Mulyar.

當然也可以用中文提問,openapi 會呼叫內建模組翻譯給你:

query = "訓練 GPT4ALL 的成本是多少?"
docs = docsearch.similarity_search(query)
chain.run(input_documents=docs, question=query)
#  根據文章,大約四天的工作,800美元的GPU成本(包括幾次失敗的訓練)和500美元的OpenAI API開銷。我們釋出的模型gpt4all-lora大約在Lambda Labs DGX A100 8x 80GB上需要八個小時的訓練,總成本約為100美元。

QA 環節發生了什麼?

根據我的理解,當你問出 who are the main author of the article? 這個問題時,發生瞭如下幾步。

第一步:呼叫 openapi 將問題進行向量化,得到一堆向量。

第二步:利用數學函式與本地向量資料庫進行匹配,找到匹配度最高的幾個文字 chunk(之前我們拆分的 PDF 文字內容)。

第三步:把這些相關度最高的文字傳送給 openapi,讓他幫我們歸納。

對於第三步是否結合了 langchain 進行多步驟對答還不得而知,下次我準備抓包看一下這個程式與 openapi 的通訊內容,才能解開其中的秘密。

當然,如果問題需要結合 PDF 所有內容才能概括出來,這種向量匹配的方式就不太行了,因為他總是傳送與問題最相關的文字片段。但是呢,因為第三步的秘密還沒有解決,很有可能當內容片段不夠時,gpt4 會詢問尋找更多相似片段,這樣不斷重複知道 gpt4 覺得可以回答了,再給出答案(想想覺得後背一涼)。

總結

解讀 PDF 的技術思路還可以用在任意問題上,比如網頁搜尋:

網頁搜尋就是一個典型的從知識海洋裡搜尋關鍵資訊並解讀的場景,只要背後將所有網頁資訊向量化,儲存在某個向量資料庫,就可以做一個 GPT 搜尋引擎了,步驟是:一、將使用者輸入關鍵字分詞並向量化。二:在資料庫進行向量匹配,把匹配度最高的幾個網頁內容提取出來。三:把這些內容餵給 GPT,讓他總結裡面的知識並回答使用者問題。

向量化可以解決任意場景模糊化匹配,比如我自己的備忘錄會儲存許多平臺賬號與密碼,但有一天搜尋 ChatGPT 密碼卻沒搜到,後來發現關鍵詞寫成了 OpenAPI。向量化就可以解決這個問題,他可以將無法匹配的關鍵詞也在備忘錄裡搜尋到。

配合向量化搜尋,再加上 GPT 的思考與總結能力,一個超級 AI 助手可做的事將會遠遠超過我們的想象。

留給大家一個思考題:結合向量化與 GPT 這兩個能力,你還能想到哪些使用場景?

討論地址是:精讀《利用 GPT 解讀 PDF》· Issue #479 · dt-fe/weekly

如果你想參與討論,請 點選這裡,每週都有新的主題,週末或週一釋出。前端精讀 - 幫你篩選靠譜的內容。

關注 前端精讀微信公眾號

版權宣告:自由轉載-非商用-非衍生-保持署名(創意共享 3.0 許可證

相關文章