Pdf2md:无需后台的PDF解析库

事实证明,PDF解析极其令人头疼。服务器端处理意味着用户需要观看20秒以上的加载动画。将PDF处理添加到我的后端增加了许多复杂性。

Pdf2md:无需后台的PDF解析库

一个月前,我开始构建一个免费开源的PDF聊天应用程序。我原本以为这会非常简单。

上传PDF,提取文本,将其提供给LLM。能出什么问题?

事实证明,PDF解析极其令人头疼。我尝试了PyMuPDF、Unstructured、Chunkr以及我能找到的每一个PDF解析库。它们要么非常缓慢,要么成本高昂,要么输出垃圾内容。服务器端处理意味着用户需要观看20秒以上的加载动画。将PDF处理添加到我的后端增加了许多复杂性。最糟糕的是,作为用户,我不喜欢这种体验。

我写了一篇文章,讲述了我在构建pdfgpt.co时的经历,但后来找到了一个更好的解决方案:一个鲜为人知的库叫做@opendocsg/pdf2md。

1、企业PDF处理灾难:没人谈论的事情

在调试我的应用时,我开始与企业工程团队讨论他们的PDF处理情况。他们处理的规模确实让我感到惊讶。一个拥有数百万活跃用户的消费者聊天应用每月处理数千万页PDF。对于另一个应用来说,这个数字达到了数亿页。

基础设施总是相同的:一个使用PyMuPDF或类似库的微服务,不断需要维护,每月花费数万美元。随着微服务的增长,它需要负载均衡器来分配流量,队列系统来应对峰值,并且需要DevOps人员不断处理各种问题。

当你考虑到浪费的时间时,成本很容易扩展到每年数十万美元,仅仅是为了在大规模上处理PDF。

这一切都始于一些无害的代码,比如:

# 将大PDF文件上传到服务器(网络延迟)  
pdf_content = await file.read()  
# 在服务器上处理(极其CPU密集型)  
markdown = extract_text_from_pdf(pdf_content)  
# 返回结果(更多网络延迟)  
return {"markdown": markdown}

我的解决方案看起来很像上面——最好的PDF处理时间仍然是几秒钟。我没有为PDF解析单独建立一个微服务——我的项目的稳定性在任何真实规模下都处于严重危险之中。

然后我发现了@opendocsg/pdf2md——一个完全在浏览器中运行的JavaScript库。没有服务器。没有上传。没有基础设施。

2、解决方案:让浏览器完成工作

现代浏览器的美妙之处在于它们非常强大。我们说的是能够处理3D图形、编译WebAssembly并处理千兆字节数据的运行环境。那么为什么我们要将PDF上传到服务器进行基本的文本提取呢?使用@opendocsg/pdf2md,整个过程都在客户端进行:

import pdf2md from '@opendocsg/pdf2md'  

async function convertPdfToMarkdown(file) {  
  // 在本地读取文件(无需上传!)  
  const arrayBuffer = await file.arrayBuffer()  

  // 在浏览器中转换为Markdown  
  const markdown = await pdf2md(arrayBuffer)  

  return markdown

就是这样。没有服务器。没有队列。没有基础设施。只是纯粹的客户端处理。

3、生产中的实际数据

pdftomarkdown.co

在通过pdftomarkdown.co处理数千份PDF后,以下是实际发生的情况:

  1. 转换速度提高了3-5倍,大型文档的改进更为显著。
  2. 零成本
  3. 零基础设施需要维护

我已经在pdftomarkdown.co开源了整个实现。你可以尝试实时演示,克隆GitHub仓库,或者部署自己的版本。这是一个完整的React组件,用于处理PDF转换:

"use client"  

import { useEffect, useState } from "react"  

interface PDF2MDLoaderProps {  
  file: File | null  
  isConverting: boolean  
  onLoad: () => void  
  onConversionComplete: (markdown: string) => void  
  onError: (error: string) => void  
}  

export default function PDF2MDLoader({ file, isConverting, onLoad, onConversionComplete, onError }: PDF2MDLoaderProps) {  
  const [pdf2md, setPdf2md] = useState<any>(null)  

  // 加载pdf2md库  
  useEffect(() => {  
    const loadPdf2md = async () => {  
      try {  
        // 动态导入pdf2md库  
        const pdf2mdModule = await import("@opendocsg/pdf2md")  
        setPdf2md(() => pdf2mdModule.default)  
        onLoad()  
      } catch (error) {  
        console.error("加载pdf2md库失败:", error)  
        onError("加载转换库失败,请稍后再试。")  
      }  
    }  

    loadPdf2md()  
  }, [onLoad, onError])  

  // 触发转换时处理  
  useEffect(() => {  
    const convertPdf = async () => {  
      if (!file || !pdf2md || !isConverting) return  

      try {  
        // 将文件转换为ArrayBuffer  
        const pdfBuffer = await file.arrayBuffer()  

        // 使用pdf2md将PDF转换为Markdown  
        const markdown = await pdf2md(pdfBuffer)  

        // 返回结果  
        onConversionComplete(markdown)  
      } catch (error) {  
        console.error("转换PDF时出错:", error)  
        onError("转换PDF失败。文件可能已损坏或不受支持。")  
      }  
    }  

    if (isConverting && file && pdf2md) {  
      convertPdf()  
    }  
  }, [file, pdf2md, isConverting, onConversionComplete, onError])  

  // 此组件不渲染任何可见内容  
  return null  
}

就是这样。它动态加载@opendocsg/pdf2md,可以在几秒钟内解析100页的PDF。

当我开始这个项目时,我只是想建立一个简单的PDF聊天应用,而不会耗尽我的AWS积分。我完全没有预料到我会发现一个可以为企业节省数百万美元的解决方案。但这就是公开解决自己问题的美妙之处。有时你为自己构建的简单解决方案正好是成千上万其他人所需要的。


原文链接:This Little-Known PDF Parsing Library Will Save Enterprises Millions

汇智网翻译整理,转载请标明出处