Интеллектуальная обработка документов с использованием сервисов искусственного интеллекта AWS и Amazon Bedrock

Умная обработка документов с применением технологий искусственного интеллекта AWS и платформы Amazon Bedrock

Компании в таких секторах, как здравоохранение, финансы, юриспруденция, розничная торговля и производство, часто обрабатывают большое количество документов в рамках своей повседневной деятельности. Эти документы часто содержат важную информацию, которая определяет своевременное принятие решений, необходимое для обеспечения высокого уровня удовлетворенности клиентов и снижения их оттока. Традиционно извлечение данных из документов осуществляется вручную, что замедляет процесс, делает его подверженным ошибкам, дорогостоящим и сложным в масштабировании. Это часто требует ручного труда, отнимающего время от важных задач. Хотя в отрасли удалось достичь некоторого уровня автоматизации с помощью традиционных инструментов OCR, эти методы оказались хрупкими, дорогостоящими в обслуживании и увеличивают технический долг. Благодаря использованию искусственного интеллекта (AI) в рамках Intelligent Document Processing (IDP), задача извлечения данных из большого количества документов различных типов и структур становится эффективной и точной. Это позволяет своевременное принятие качественных деловых решений при сокращении общих затрат.

Кроме того, создание моделей AI с использованием больших языковых моделей (LLM) добавляет мощные возможности к решениям IDP, устраняя пробелы, которые раньше существовали даже с высокообученными моделями машинного обучения. В этой статье я кратко рассмотрю различные фазы IDP и то, как генеративный AI используется для усиления существующих рабочих нагрузок или разработки новых рабочих нагрузок IDP.

Фазы Intelligent Document Processing

На высоком уровне стандартный рабочий процесс IDP состоит из четырех фаз: хранение документов, документная классификация, извлечение и обогащение. Обратите внимание, что не все случаи использования включают реализацию всех этих фаз, но наиболее распространенные случаи использования являются комбинацией нескольких из этих фаз, причем наиболее популярными фазами являются классификация документов и фаза извлечения. Ниже представлена диаграмма, иллюстрирующая эти фазы IDP. В этой статье мы сосредоточимся в основном на классификации документов и фазе извлечения, а также на используемых компонентах и механизмах искусственного интеллекта. Для каждой из этих фаз IDP мы кратко обсудим важность фазы и более подробно рассмотрим реализацию с помощью генеративного искусственного интеллекта и машинного обучения. Мы также обсудим некоторые облачные службы искусственного интеллекта, такие как Amazon Comprehend, Amazon Textract и модели LLM через Amazon Bedrock. Мы также рассмотрим детали реализации с популярной библиотекой LangChain Python с открытым исходным кодом.

Рисунок 1: Фазы Intelligent Document Processing

Классификация документов

Частой проблемой при работе с большим количеством документов является их идентификация, сортировка по категориям и последующая обработка. Традиционно это процесс, основанный на действиях человека или эвристике, но с увеличением объема документов такие методы становятся узким местом бизнес-процессов и результатов. Основная идея этой фазы заключается в автоматизации категоризации или классификации с использованием искусственного интеллекта. В этой фазе документы, которые в противном случае являются неизвестными или могут быть четко классифицированы в отдельные категории, классифицируются и маркируются с использованием искусственного интеллекта в автоматическом режиме. Для классификации документов мы используем модели пользовательских классификаторов Amazon Comprehend.

СОБЫТИЕ – ODSC West 2023

Очное и виртуальное мероприятие

С 30 октября по 2 ноября

Присоединяйтесь к нам, чтобы вникнуть в последние тенденции в области науки о данных и искусственного интеллекта, инструменты и методики, от LLM до анализа данных и от машинного обучения до ответственного искусственного интеллекта.

С помощью Amazon Comprehend мы можем обучать нашу пользовательскую модель классификации документов, которая адаптирована специально для идентификации документов в вашем конкретном случае. Модель учитывает структуру документа, а также его содержимое (текст) для выполнения классификации документов. Вы можете обучить одну модель для классификации документов на 1000 различных классов, и документы могут быть в форматах PDF, JPG, PNG, DOCX или TXT. Документы могут быть одностраничными или многостраничными. Для многостраничных документов модель выдает класс документа на уровне страницы вместе с оценками уверенности.

Классификация документов с помощью LLM – это еще одна развивающаяся техника, которую организации могут применять для расширения своего процесса классификации. Это полезно, если в процесс поступают новые документы, с которыми модели не были обучены. Это также полезно, когда существующая обученная модель классификатора классифицирует документ с крайне низкой точностью. Такая ситуация часто возникает при работе с нагрузками машинного обучения, поскольку бизнес-процессы развиваются. Вот как может выглядеть возможная реализация классификации документов с использованием модели Amazon Bedrock и Anthropic Claude-v1. Мы используем возможности извлечения текста из документа Amazon Textract с помощью LangChain, а затем используем инженерию запросов для определения возможной категории документа. LangChain использует API Amazon Textract – DetectDocumentText для извлечения текста из печатных, отсканированных или рукописных документов.

Рисунок 2: Низкий балл классификации направляется в LLM для классификации

```from langchain.document_loaders import AmazonTextractPDFLoaderfrom langchain.llms import Bedrockfrom langchain.prompts import PromptTemplatefrom langchain.chains import LLMChainloader = AmazonTextractPDFLoader("./samples/document.png")document = loader.load()template = """Учитывая список классов, классифицировать документ в один из этих классов. Пропустить любой предисловие и просто указать название класса.<classes>INVOICE, BANK_STATEMENT, HEALTH_PLAN, PRESCRIPTION</classes><document>{doc_text}<document><classification>"""prompt = PromptTemplate(template=template, input_variables=["doc_text"])bedrock_llm = Bedrock(client=bedrock, model_id="anthropic.claude-v1")llm_chain = LLMChain(prompt=prompt, llm=bedrock_llm)class_name = llm_chain.run(document[0].page_content)print(f"Предоставленный документ = {class_name}")—-Предоставленный документ = HEALTH_PLAN```

Обратите внимание, что мы используем здесь модель anthropic.claude-v1, у которой окно контекста токенов составляет 100 000 токенов. Это действие также может выполняться с помощью модели Anthropic Claude v2, у которой также окно контекста токенов составляет 100 000, однако стоимость может значительно варьироваться в зависимости от выбранной модели. В целом, модели Anthropic Claude Instant и Claude v1 являются отличными универсальными моделями и подходят для большого числа случаев использования. В следующем коде демонстрируется механизм отслеживания, который показывает количество токенов вводного запроса и сгенерированного текста.

```prompt = PromptTemplate(template=template, input_variables=["doc_text"])bedrock_llm = Bedrock(client=bedrock, model_id="anthropic.claude-v1")num_in_tokens = bedrock_llm.get_num_tokens(document[0].page_content)print (f"Наш вводной запрос содержит {num_in_tokens} токенов \n\n=========================")llm_chain = LLMChain(prompt=prompt, llm=bedrock_llm)class_name = llm_chain.run(document[0].page_content)num_out_tokens = bedrock_llm.get_num_tokens(class_name)print (f"Наш вывод содержит {num_out_tokens} токенов \n\n=========================")print (f"Общее количество токенов = {num_in_tokens + num_out_tokens}")—-Наш вводной запрос содержит 1295 токенов =========================Наш вывод содержит 9 токенов =========================Общее количество токенов = 1304```

Извлечение документов

Извлечение документов, возможно, является самым популярным этапом работы с ВПТ. Большинство случаев использования, с которыми я сталкиваюсь в своей повседневной работе с ВПТ, сильно отклоняется к различным механизмам извлечения различной информации из самых разных документов. Документы варьируются от свидетельств о рождении, ипотечных договоров, налоговых форм, резюме, отчетов по медицинским испытаниям, документов по медицинскому страхованию, удостоверений личности (паспортов, лицензий и т. д.), рекламных материалов, вырезок из газет и так далее. Как вы можете себе представить, форматы и типы документов сильно отличаются в зависимости от случая использования и зачастую внутри одного случая использования. Поэтому существует несколько различных способов извлечения информации из всех этих различных типов документов. Однако важно помнить, что пока не существует “универсальной” модели искусственного интеллекта, которая способна извлекать данные из всех этих документов в требуемом формате. Но хорошая новость в том, что существует множество специализированных и универсальных моделей, которые могут помочь нам достичь наших целей в области извлечения документов.

Amazon Textract предоставляет ряд универсальных функций, таких как извлечение форм, извлечение таблиц, запросы и макеты. Эти функции работают с практически любым документом и отлично подходят для извлечения документов общего назначения, таких как извлечение из форм или документов, содержащих табличные данные. Amazon Textract также предоставляет некоторые специальные модели искусственного интеллекта, такие как AnalyzeID для распознавания и извлечения информации из американских удостоверений личности, AnalyzeExpense, который умеет читать и извлекать информацию из счетов и квитанций, и AnalyzeLending, способный идентифицировать и извлекать информацию из ипотечных и кредитных документов. Более подробную информацию о работе этих моделей можно найти в связанной выше документации, но в этом разделе мы сосредоточимся на техниках извлечения документов на основе LLM. Мы будем особенно сосредоточены на двух самых распространенных сценариях использования: извлечении сущностей по шаблону и вопросно-ответной системе на основе больших языковых моделей.

Извлечение сущностей по шаблону

В практически всех случаях использования IDP извлеченные данные в конечном итоге отправляются в систему для дальнейшей обработки или анализа. Важно иметь нормализованный вывод из экстракции, чтобы механизм потребления и код интеграции были легко поддерживаемыми, более надежными и менее хрупкими. Набор детерминированных ключей может сделать большую разницу в вашем коде интеграции по сравнению с недетерминированными ключами. Например, рассмотрим случай использования, включающий извлечение имени, фамилии и даты рождения заявителя. Однако вовлеченные документы могут или не могут иметь эти имена четко обозначены как “Имя”, “Фамилия”, “Дата рождения” и могут поступать в разных форматах.

Обработка интеллектуальных документов с помощью сервисов искусственного интеллекта AWS и Amazon BedrockРисунок 3: Фактический вывод извлечения документа по сравнению с желаемым выводом

Обратите внимание на разницу между фактическим выводом и желаемым выводом. Желаемый вывод следует более детерминированной схеме, что делает нашу логику постобработки гораздо более простой, легкой в поддержке и менее затратной для разработки. Это достигается с помощью больших языковых моделей, как показано в приведенном ниже коде.

```from langchain.document_loaders import AmazonTextractPDFLoaderfrom langchain.llms import Bedrockfrom langchain.prompts import PromptTemplatefrom langchain.chains import LLMChainloader = AmazonTextractPDFLoader("./samples/document.png")document = loader.load()output_template= {    "first_name":{ "type": "string", "description": "Имя заявителя" },    "last_id":{ "type": "string", "description": "Фамилия заявителя" },    "dob":{ "type": "string", "description": "Дата рождения заявителя" },}template = """Вы — полезный помощник. Пожалуйста, извлеките следующие данные из документа и отформатируйте вывод в формате JSON, используя указанные ключи. Пропустите любой предварительный текст и сгенерируйте окончательный ответ.<details>{details}</details><keys>{keys}</keys><document>{doc_text}<document><final_answer>"""details = "\n".join([f"{key}: {value['description']}" for key, value in output_template.items()])keys = "\n".join([f"{key}" for key, value in output_template.items()])prompt = PromptTemplate(template=template,                         input_variables=["details", "keys", "doc_text"])bedrock_llm = Bedrock(client=bedrock, model_id="anthropic.claude-v1")llm_chain = LLMChain(prompt=prompt, llm=bedrock_llm)output = llm_chain.run({"doc_text": full_text, "details": details, "keys": keys})print(output)—-{  "first_name": "Джон",  "last_name": "Доу",  "dob": "26 июня 1981"}```

В этом случае, просто создавая нашу инструкцию с ясными указаниями для LLM, мы смогли не только извлечь сущности, но также получить вывод в формате, соответствующем нашей собственной схеме. Это важно с точки зрения последующей обработки теперь, когда наш код интеграции стал намного проще и более детерминированным. Кроме того, LangChain также предоставляет встроенный способ создания этих инструкций более модульным способом. Вот как выглядит код.

```from langchain.output_parsers import ResponseSchemafrom langchain.output_parsers import StructuredOutputParserresponse_schems = list()for key, value in output_template.items():    schema = ResponseSchema(name=key,                             description=value['description'],                             type=value['type'])    response_schems.append(schema)output_parser = StructuredOutputParser.from_response_schemas(response_schems)format_instructions= output_parser.get_format_instructions()print(format_instructions)—-Выходным кодом должен быть фрагмент кода в формате markdown со следующей схемой, включая ведущие и завершающие "```json" и "```":```json{"first_name": string  // Имя заявителя"provider_id": string  // Фамилия заявителя"dob": string  // Дата рождения заявителя}``````

Затем мы просто можем использовать эту предварительно сгенерированную инструкцию форматирования (в переменной format_instruction) с нашей цепочкой LLM следующим образом.

```template = """Вы - полезный помощник. Пожалуйста, извлеките следующую информацию из документа и строго следуйте инструкциям, описанным в инструкции по форматированию, чтобы отформатировать выходные данные. Пропустите любой преамбул текст и сгенерируйте окончательный ответ.<details>{details}</details><format_instructions>{format_instructions}</format_instructions><document>{doc_text}<document><final_answer>"""llm_chain = LLMChain(prompt=prompt, llm=bedrock_llm)output = llm_chain.run({"doc_text": full_text,                         "details": details,                         "format_instructions": format_instructions})parsed_output= output_parser.parse(output)parsed_output```

Вопросы и ответы на документы с улучшенным поколением извлечения (RAG)

Второй самый распространенный подход к извлечению информации из документов – использование метода вопросов и ответов в виде чата. Этот метод предполагает задавание вопроса модели LLM на основе содержимого документа в надежде получить ответ из самого документа (если доступно). Однако есть несколько проблем, которые требуют активного устранения – предотвращение галлюцинаций модели и ограничение контекста токенов.

Большие предварительно обученные языковые модели демонстрируют результаты научных исследований во многих задачах NLP благодаря сохраненным фактическим знаниям. Однако их точность в обработке знаний ограничена, что приводит к субоптимальной производительности в задачах, требующих высокого уровня знаний. Для смягчения этого проблемы был разработан подход, известный как Улучшение поколения с помощью извлечения. Этот метод не только помогает LLM давать точные ответы на вопросы в контексте документа, но также предотвращает появление галлюцинаций и ограничивает объем токенов LLM для больших документов. Идея RAG заключается в том, чтобы собирать только те части документа, которые семантически ближе к заданному вопросу. Это достигается разделением содержимого документа на несколько меньших частей, генерацией векторных вложений для них и хранением вложений в векторной базе данных. Векторная база данных может выполнять поиск по сходству или поиск с максимальной маржинальной релевантностью (MMR) для сбора наиболее подходящих фрагментов из документа. После получения этих соответствующих фрагментов создается полный контекст с вопросом с некоторой инженерией промта, чтобы получить наиболее точный ответ от модели.

Intelligent Document Processing with AWS AI Services and Amazon BedrockРис. 4: Улучшенное поколение с помощью извлечения с помощью вложений документов и векторной базы данных

На представленной фигуре мы используем модель Titan Embeddings G1 – Text через Amazon Bedrock для генерации вложений текстовых фрагментов. Большая часть механизма RAG может быть выполнена с использованием полезных встроенных модулей библиотеки LangChain, включая разбиение на фрагменты, генерацию вложений и загрузку векторной базы данных по вашему выбору, а затем выполнение RAG-основанного вопросно-ответного действия с содержимым документа с использованием векторной базы данных в качестве получателя. В следующем коде приведен пример возможной реализации такого механизма с использованием цепочки LangChain’s RetrievalQA, выполняющей поиск по сходству, создание контекста, дополнение промта с использованием контекста внутренним способом. В данном примере мы используем хранилище векторов [FAISS](https://ai.meta.com/tools/faiss/#:~:text=FAISS%20(Facebook%20AI%20Similarity%20Search,more%20scalable%20similarity%20search%20functions.) в качестве векторной базы данных.

```from langchain.embeddings import BedrockEmbeddingsfrom langchain.vectorstores import FAISSfrom langchain.document_loaders import AmazonTextractPDFLoaderfrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain.llms import Bedrockfrom langchain.prompts import PromptTemplatefrom langchain.chains import LLMChainloader = AmazonTextractPDFLoader(f"./samples/document.png")document = loader.load()text_splitter = RecursiveCharacterTextSplitter(chunk_size=400,                                               separators=["\n\n", "\n", ".", "!", "?", ",", " ", ""],                                               chunk_overlap=0)texts = text_splitter.split_documents(document)embeddings = BedrockEmbeddings(client=bedrock,                               model_id="amazon.titan-embed-text-v1")vector_db = FAISS.from_documents(documents=texts,                                  embedding=embeddings)retriever = vector_db.as_retriever(search_type='mmr',                                    search_kwargs={"k": 3})template = """Ответьте на вопрос максимально точно, используя только предоставленный текст. Если ответ не содержится в тексте, скажите "Не знаю". Пропустите любой вводный текст и рассуждения, и дайте только ответ.<text>{document}</text><question>{question}</question><answer>"""prompt = PromptTemplate(template=template,                         input_variables=["document","question"])bedrock_llm = Bedrock(client=bedrock,                       model_id="anthropic.claude-v1")llm_chain = LLMChain(prompt=prompt, llm=bedrock_llm)answer = llm_chain.run(document=full_context,                        question="Что такое вылет из кармана аптеки на одного человека?")print(f"Ответ: {answer.strip()}")—-Ответ: $6,000```

В этом примере мы извлекли документ с помощью Amazon Textract, получив текст для каждой страницы. Затем мы разбиваем все страницы документа на фрагменты по 400 символов. Последовательно генерируем векторные эмбеддинги фрагментов и сохраняем их в векторное хранилище FAISS, используя его в качестве поисковика для механизма вопросов и ответов на основе RAG. Подробное описание процесса шаг за шагом можно найти в этом репозитории GitHub с полным набором Python Notebooks.

Заключение

В этой статье мы рассмотрели различные фазы интеллектуальной обработки документов и исследовали некоторые способы использования генеративного искусственного интеллекта с помощью Amazon Bedrock для дополнения или улучшения рабочего процесса IDP. Существует несколько других видов извлечений, которые мы не рассмотрели в этой статье, таких как суммирование, ответы на вопросы по таблице с самоопросом, стандартизация и так далее. Вы можете узнать больше о каждом из этих типов извлечений, используя Python notebooks в упомянутом выше репозитории GitHub. Если вы уже используете рабочий процесс IDP для вашего случая использования, генеративный ИИ предоставляет совершенно новые возможности, дополняя ваш рабочий процесс возможностями LLM. Если вы находитесь в фазе принятия решения о рабочем процессе IDP для вашего случая использования, стоит изучить все различные способы, которыми генеративный ИИ может добавить ценности.

Об авторе

Анжан Бисвас – ведущий специалист-разработчик искусственного интеллекта в Amazon Web Services (AWS). Анжан специализируется в области компьютерного зрения, обработки естественного языка и генеративных технологий искусственного интеллекта, большую часть своего времени работает над задачами интеллектуальной обработки документов (IDP). У него более 16 лет опыта в создании крупномасштабных предприятческих систем в области поставок, розницы, технологий и здравоохранения, и он увлечен наукой о данных и машинным обучением.