在本文中,我将讨论一个非常基本的信息提取管道可能是什么样子,以及如何使用 LangChain 和 Streamlit 等现代 Python 框架,轻松地围绕 LLM 构建 Web 应用程序。
方法
光学字符识别
光学字符识别(OCR)是指从图像中提取出机器可读格式的文本。在任何信息提取产品或服务中,首先要做的就是从文档中提取文本。该文档可以是PDF文件或扫描/拍摄的图像。最终,PDF被转换成一系列图像,其中每一页被转换成一张单独的图像。因此,OCR模型原生地只处理图像。
项目中的OCR类是一个Python协议,可以扩展以实现不同的付费OCR服务,如Tesseract、AWS Textract、Azure视觉API等。
from typing import Protocol
class OCR(Protocol):
"""
OCR Protocol Class
"""
def get_text_response(self, images: list) -> list:
pass
使用Tesseract扩展OCR
import pytesseract
from ocr import OCR
class TesseractOCR(OCR):
def get_text_response(self, images: list) -> list:
"""Generates ocr response from list of images
Args:
images (list): list of images to be processed.
Returns:
list: list of ocr responses for each image.
"""
pdf_texts = []
for image in images:
text = pytesseract.image_to_string(image)
pdf_texts.append(text)
return pdf_texts
同样地,现有的OCR协议也可以扩展实现其他类别的OCR产品,比如AWS Textract和Azure Vision。
LangChain抽取和模式构建器
模式构建器
为了从LLM获得结构化的输出,模式是一系列属性的集合。模式将按照提供的格式输出结果。模式中的每一个属性都需要定义三个属性:属性的名称、属性的类型、以及这个属性是否是必需的。
一旦模式构建完成,它就可以用来从LLM生成一个结构化的输出。
在上图中,输入作为LLM的上下文。模式为输出的格式提供了框架,并且还指定了需要提取的字段及其对应的数据类型。LangChain支持的可能的数据类型有“字符串”和“整数”。一旦我们有了上下文和模式,这些可以输入到LLM以生成响应。
LangChain
LangChain是一个用于开发应用程序的框架,这些应用程序利用了语言模型的能力。它可以使应用程序:
在这篇文中,与提取相关的LangChain函数已经被使用。它可以用来获取带有指定模式的结构化模型输出。
"""
LLM Handler Code
"""
from langchain.chat_models import ChatOpenAI
from langchain.chains import create_extraction_chain
class LLM:
"""Handles communication with OpenAI LLMs"""
def __init__(self, temperature: float, openai_api_key: str) -> None:
self.llm = ChatOpenAI(temperature=temperature, openai_api_key=openai_api_key)
def analyze_text(self, text: str, schema: dict) -> dict:
"""Analyze text according to schema
Args:
text (str): OCR Output to be analyzed
schema (dict): Schema to be processed
Returns:
dict: LLM Response
"""
chain = create_extraction_chain(schema, self.llm)
return chain.run(text)
那么,流水线大致是这样的,我们从OCR模块获取机器可读格式的文本,我们还构建了模式(schema)来指定我们输出结构的格式。
OCR输出的文本就是上下文,而模式构建器(schema builder)帮助我们准备所需格式的模式。一旦我们拥有这两者,我们就使用LangChain的create_extraction_chain函数来生成输出。
Streamlit前端
Streamlit是什么?
所有机器学习应用都需要一个交互式的网络应用程序,它可以使展示其结果和性能变得更加容易。Streamlit是一个免费、开源、全Python框架,它使数据科学家能够快速构建交互式仪表板和机器学习网络应用程序,而无需前端网络开发经验。
为了展示使用Streamlit和Langchain构建交互式应用程序是多么容易,这里有一个代码片段和生成的网络应用程序。
import streamlit as st
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
# Streamlit App Title
st.title("?? Langchain - Blog Outline Generator App")
# OpenAI API key required to access their APIs
openai_api_key = st.sidebar.text_input("OpenAI API Key", type="password")
def blog_outline(topic:str):
# Instantiate LLM model
llm = OpenAI(model_name="gpt-3.5-turbo-instruct", openai_api_key=openai_api_key)
# Prompt
template = "As an experienced data scientist and technical writer, generate an outline for a blog about {topic}."
prompt = PromptTemplate(input_variables=["topic"], template=template)
prompt_query = prompt.format(topic=topic)
# Run LLM model
response = llm(prompt_query)
# Print results
return st.info(response)
with st.form("myform"):
topic_text = st.text_input("Enter prompt:", "")
submitted = st.form_submit_button("Submit")
if not openai_api_key:
st.info("Please add your OpenAI API key to continue.")
elif submitted:
blog_outline(topic_text)
Streamlit
关于Streamlit需要注意的一点是,每当有人与应用程序“互动”时,脚本都会从头到尾重新执行。这里所说的互动,意味着点击按钮或移动滑块。因此,为了构建具有多个阶段的Streamlit应用程序,在编写代码时使用状态设计模式是有益的。
以上是状态图以及在此信息提取应用程序的代码中使用的转换。为遵守状态设计模式的规则,使用了名为Transitions的Python包,它提供了一个轻量级的状态机实现。但是,也可以实现自己的状态机。
应用程序
欢迎界面
提示你输入OpenAPI密钥以继续进行。我还提供了一个功能,允许你免费尝试多达五次。
文件上传界面
等待上传文件,无论是图片或PDF都可进行上传。也可以上传多个文件。应用程序支持JPG、PNG和PDF文件格式。
架构生成器屏幕
在这里,可以构建架构来接收来自OpenAI提取API的结构化输出。
LLM输出屏幕
最终输出屏幕显示了从提取API的输出作为一个数据框架。每个上传的文件都被分析,其输出显示在一个单独的标签页中。侧边栏还显示了原始架构,并且可以更改它以重新分析所有文档。
因此,在这个例子中,我上传我的简历作为系统要分析的文档。因为我的简历包含我的姓名、地址和其他联系方式。因此,为了提取它们,我指定了在架构生成器阶段要提取的“人员姓名”和“联系电话”字段。
因此,正如你在 LLM 输出屏幕中看到的那样,数据框的列是我指定的字段,值是 OpenAI LLM 输出的值。
结论
这个应用程序有效地展示了大型语言模型的强大以及它们在不同文档上的良好泛化能力。借助LLM,信息提取任务已经变得相当容易。另外,使用Streamlit,即使是只有Python知识而没有之前的前端经验的人也可以轻松开发一个非常现代化的前端。它是构建基于机器学习模型的概念验证和小型应用程序的完美框架。