Ingesta de datos

Explore más de lo que el RAG Cookbook ofrece para obtener insights más profundos sobre las soluciones RAG actuales

Un espacio principal recoloreado que utiliza como base el espacio principal watsonx para atención al cliente.
Descripción general

La ingestión es el proceso de analizar la información de los documentos fuente para que pueda integrarse en un espacio de búsqueda y recuperarse posteriormente. Si bien este es un proceso sencillo para el texto sin formato, surgen complicaciones cuando los documentos originales no están en formato de texto, por ejemplo, Microsoft Word o PDF, y cuando contienen formatos complejos, como encabezados y pies de página repetidos, texto en varias columnas o tablas.

Esta sección contiene consejos, técnicas, aceleradores e indicaciones sobre recursos que ayudan a superar estos desafíos.

¿Por dónde empezar?

 

Si no tiene conocimientos técnicos, sus documentos son relativamente sencillos y necesita una solución sin código, utilice Watsonx Orchestrate.

 

Si es un usuario técnico y sus documentos son relativamente simples y tiene acceso a Watson Discovery, comience desde allí. Watson Discovery tiene una interfaz de usuario (IU) agradable para usar con una necesidad mínima de programación. Para documentos complejos, puede usar Watson Discovery para anotar y extraer partes específicas de sus documentos, ya sea para su pipeline de backend de RAG o para front end y resaltar los textos obteniendo la posición exacta de un párrafo dentro de sus documentos.

 

Sin embargo, Watson Discovery tiene sus limitaciones. Si sus documentos tienen más de 50 MB, no podrá cargarlos en Watson Discovery. Si el documento es demasiado complejo (es decir, incluye tablas anidadas o formatos de tablas irregulares), es posible que Watson Discovery no capture toda la estructura del documento. Quizá quiera implementar un pipeline personalizado de ingestión de datos usando bibliotecas de código abierto para estos casos.

 

Con respecto a las bibliotecas de código abierto, LangChain y LlamaIndex son muy similares en términos de capacidades de ingesta de datos. Sin embargo, LangChain sería más fácil de usar que LlamaIndex en términos de documentación e integración con bases de datos vectoriales y otras aplicaciones. Tanto LangChain como LlamaIndex tienen funciones auxiliares que pueden convertir un objeto documento de uno a otro, por lo que el cambio entre LangChain y LlamaIndex se puede realizar en cualquier punto de su pipeline.

Ingesta de documentos con tablas complejas

Las siguientes notas incluyen varias lecciones aprendidas para la ingestión de documentos que incluyen tablas complejas y diferentes enfoques que se probaron durante uno de los proyectos. Tenga en cuenta que algunas de las observaciones pueden ser diferentes de un proyecto a otro; sin embargo, la mayoría de las conclusiones deben ser similares para los proyectos que incluyen documentos con tablas anidadas y complejas.

Watson Discovery

Watson Discovery no admite documentos de más de 50 MB. En los casos en que el gran tamaño se debe al hecho de que los documentos originales están en formato Word, necesitamos convertir los documentos originales de Word a PDF para usar Watson Discovery. Sin embargo, con este enfoque, Watson Discovery a veces no puede capturar formatos de tabla correctamente, especialmente en casos de tablas complejas o anidadas.

Para la ingesta con Watson Discovery se pueden probar dos enfoques diferentes: un modelo ya entrenado y un modelo de usuario entrenado anotando manualmente algunas páginas a través de la comprensión inteligente de documentos de Discovery. A continuación se analizan las lecciones aprendidas de estos dos enfoques para uno de los proyectos que incluía tablas anidadas complejas.

  • modelo preentrenadol
    • Pros: 
      • La salida HTML de Discovery a menudo podía capturar la estructura de las tablas mejor que un modelo entrenado por el usuario (SDU)
    • Contras: 
      • Discovery seguía teniendo dificultades para detectar tablas anidadas. En algunos casos, solo vería la tabla más interna como una tabla y capturaba las tablas externas como texto, perdiendo la estructura de datos.
    • Al utilizar Watson Discovery, el uso del texto sin procesar puede dar mejores resultados en comparación con el uso de salidas HTML.  

  • modelo definido por el usuario
    • Pros: 
      • Muy fácil de anotar y adecuado para documentos sencillos en los que se desea filtrar secciones específicas más adelante.
    • Contras:
      • No pudimos detectar las estructuras de tablas anidadas aunque anotábamos todas las tablas dentro de las tablas.
      • Incluso con las tablas más simples, tenía problemas para detectarlas en documentos nuevos, incluso después de anotar manualmente 20 páginas de más de 7 documentos.

Aunque los resultados de Watson Discovery no fueron tan precisos como otras bibliotecas personalizadas mencionadas a continuación para tablas complejas y anidadas, los resultados incluyeron muchos metadatos, como números de página y coordenadas de los textos, que son útiles para mostrar los aspectos más destacados de la interfaz de usuario (IU). Estos metadatos pueden resultar muy útiles para añadir filtros adicionales durante la recuperación o incluso para dividir los documentos en función de determinadas secciones HTML.

PyPDFLoader vs PyMuPDF

La biblioteca PyMuPDF es mucho más rápida y da como resultado resultados más precisos, especialmente en datos más grandes. Con las siguientes dos funciones en un conjunto de datos de 50.6 MB, PyMuPDF tardó 0.131 segundos frente a 0.366 segundos con PypdfLoader de LangChain. Por lo tanto, para archivos grandes y si no desea extraer secciones separadas del documento como secciones separadas, use la biblioteca PyMuPdf.

def pdf_to_text(path: str,
                        start_page: int = 1,
                        end_page: Optional[int | None] = None) -> (list[str], list[str], list[dict]):
    """
    Converts PDF to plain text.

   
        Params: ruta (str): ruta al archivo PDF.
        start_page (int): Página para empezar a recibir texto.
        end_page (int): Última página para obtener texto.
   
    """ logger.debug("Processing PDF%s".format(path))

   

    from langchain_community.document_loaders import PyPDFLoader loader = PyPDFLoader(path) pages = loader.load()
   
    total_pages = len(páginas)
    logger.debug(f'Total páginas: {total_pages}')
_ids = []
_metadata = []
_nombre_archivo = Ruta(ruta).nombre

    si end_page es None:
end_page = len(páginas)

_text_list = []
para índice en rango(página_inicial - 1, página_final):
texto = páginas[índice].contenido_página
        texto = texto.replace('\n', ' ')
        texto = re.sub(r'\s+', ' ', mensaje)
        _text_list.append(texto)
        _ids.append(f'page_{index + 1}')
        _metadata.append({
            "id": index + 1,
            "file_name": _file_name,
            "page": f'page {index + 1}'
       

   


                       
                       
                       
   
}) return _text_list, _ids, _metadata def large_pdf_to_text(path: str, start_page: int = 1, end_page: Optional[int | None] = None, remove_string_list=None) -> (list[str], list[str], list[dict]): """ Convierte PDF a texto sin formato mediante PyMuPDF, una velocidad de ejecución impresionante, lo que lo hace adecuado para el procesamiento de PDF a gran escala.
Aunque no ofrece características dedicadas para la extracción de tablas,
puede utilizarse para analizar la estructura del PDF y extraer datos tabulares con pasos de procesamiento adicionales si es necesario.


        50.6MB - > 0.131 segundos (PyMUPDF) vs 0.366 segundos (pypdf)

Paramáms:
file_stream (stream): Transmite al archivo PDF.
            path (str): Ruta al PDF
start_page (int): Página desde la que comenzar a obtener el texto.
            end_page (int): Última página para obtener texto.
            remove_string_list (list[str]): Eliminar lista de cadenas.
       
    """ logger.debug("Processing PDF%s".format(path))
    si remove_string_list es None:
remove_string_list = []

import fitz

# pdf_reader = fitz.open(stream = file_stream, filetype = "pdf")
pdf_reader = fitz.open(path)
    si end_page es None:
end_page = pdf_reader.page_count

    _text_list = []
_ids = []
_metadata = []
_nombre_archivo = Ruta(ruta).nombre
   
        for index in range(start_page - 1, end_page): text = pdf_reader[index].get_text("text")
        texto = texto.replace('\n', ' ')
        texto = re.sub(r'\s+',
       
            ' ', text) for remove_string in remove_string_list: re_compile = re.compile(remove_string)
            texto = re_compile.sub('', texto)
            _metadata.append({
                "id": index + 1,
                "file_name": _file_name,
                "page": f'page {index + 1}'
            })
        _ids.append(f'page_{index + 1}')
        _text_list.append(texto)

    return _text_list, _ids, _metadata

Cargador de PDF no estructurado para la ingesta de html UnstructuredPDFLoader de LangChain

  • Pros: 
    • Se incluyeron muchos metadatos, como números de página y coordenadas x, y de los textos, similares a los de watson Discovery, que podrían ser útiles para mostrar lo más destacado más adelante.
  • Contras: 
    • No puedo capturar muchas tablas anidadas o complejas correctamente. Además, para este enfoque necesitábamos convertir cada uno de los formatos docx originales a PDF.

Cargador de Word no estructurado para la ingesta de HTML UnstructuredWordDocumentLoader de LangChain

  • Pros: 
    • El uso de Docs dio como resultado una mejor captura de las tablas y ayuda en un mejor contexto para que los LLM generaran respuestas.
  • Contras: 
    • Los metadatos, como los números de página, no se capturaban correctamente incluso después de agregar saltos de página en comparación con el cargador de PDF.

Resumen de tablas HTML

En un intento por preservar la estructura de las tablas, ingresamos elementos de la tabla desde el HTML extraído (usando una biblioteca no estructurada) en un LLM (Mixtral para tablas largas es una buena opción debido a su tamaño de contexto), luego se puede crear una instrucción para resumir las tablas o usar un aprendizaje rápido para convertir las tablas a un formato que creemos que podría ser más comprensible para los modelos de lenguaje grandes.

  • Pros: 
    • El texto de salida sería más fácil de fragmentar e ingerir y preservaría la estructura de las tablas.
  • Contras: 
    • En tablas de gran tamaño de varias páginas, para la instrucción de resumen podríamos perder algo de información, por lo que los pocos intentos de aprender a convertir las tablas en lugar de resumirlas podrían dar como resultado mejores resultados.

También se probaron otras bibliotecas de lectores de tablas, como camelot y tabula, sin embargo, estas bibliotecas no fueron tan precisas como las no estructuradas para tablas complejas y, dado que solo detectan tablas dentro de un documento, es posible que se necesite más preprocesamiento para crear fragmentos significativos para pasar al lenguaje grande modelos.

Para concluir, aunque Watson Discovery sería una forma fácil y rápida de realizar una ingesta de documentos y capturar una gran cantidad de metadatos adicionales que pueden ser útiles para crear la interfaz de usuario (IU) (para resaltar los fragmentos, por ejemplo), la biblioteca "no estructurada" (que tiene contenedores tanto en LlamaIndex como en LangChain) podía capturar las tablas complejas dentro de los documentos con mayor precisión que Watson Discovery. Por lo tanto, una combinación de ambos enfoques puede resultar útil para proyectos que incluyen tablas complejas en sus documentos.

Herramientas de IBM

Ingestión con Watsonx Orchestrate

La ingestión sin una interfaz gráfica puede ser difícil para los usuarios empresariales, ya que requiere experiencia y conocimientos técnicos. watsonx Orchestrate elimina la frustración de los usuarios empresariales mediante la implementación de una interfaz de usuario (IU) de arrastrar y soltar. Al hacer clic en el botón azul de carga, iniciamos la capacidad de cargar y almacenar documentos directamente en watsonx Discovery (también conocido como Elasticsearch).

Captura de pantalla del portal de arrastrar y soltar de watsonx Orchestrate

Esto permite al usuario cargar directamente en Elasticsearch su documentación para crear su propia base de conocimientos personalizada.

Captura de pantalla de la pantalla de carga de documentos en watsonx Orchestrate

En lugar de ingerir directamente los documentos en Watsonx Discovery, también tiene la opción de conectarte a Watson Discovery a través de Watsonx Orchestrate. A continuación encontrará más detalles sobre cómo realizar la ingesta de datos a través de Watson Discovery.

Watson Discovery

Una de las otras herramientas internas que se pueden utilizar para la ingesta es Watson Discovery. Watson Discovery no es puramente una herramienta de ingesta y, con ella, puede ingerir, normalizar, enriquecer y buscar sus datos no estructurados. La siguiente imagen muestra los componentes principales y las capacidades de Watson Discovery.

Ilustración de las funciones principales de Watson Discovery

Como puede ver, una de las capacidades principales de Watson Discovery es la ingesta de datos estructurados y no estructurados en diferentes formatos, como JSON, HTML, PDF, Word y más, y Smart Document Understanding.

Si tiene Watson Discovery aprovisionado en su entorno, puede realizar la ingesta de documentos fácilmente creando primero un proyecto y luego creando una colección donde puede cargar sus datos desde el almacenamiento local o una ubicación en la nube, como un bucket de object storage.

Una vez que haya creado su colección, puede ir a la pestaña Administrar colecciones en el menú hamburguesa y luego, en Campos de identidad, puede elegir qué método desea utilizar para procesar los documentos.

Captura de pantalla de la pantalla de procesamiento de documentos de Watson Discovery

Hay tres opciones:

  • Solo extracción de texto: extrae solo textos de los documentos.
  • Modelos entrenados por el usuario: donde puede anotar diferentes partes de su documento con etiquetas personalizadas y entrenar sus propios modelos basados en patrones visuales repetidos dentro de sus documentos
  • modelos previamente entrenados: pueden extraer texto e identificar tablas, listas y secciones utilizando modelos de IBM previamente entrenados.

Puede pasar un tiempo hasta que se procesen todos sus documentos. Después de eso, puede usar Watson Discovery API para leer y usar sus datos en su código.

A continuación se muestra un código de ejemplo que muestra cómo se puede utilizar la API para leer los datos de su colección:

from langchain.docstore.document import Document
import os
import logging
import time
from ibm_watson import DiscoveryV2
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

WD_PAGE_SIZE = 200
MAX_RETRIES = 2
def get_documents_from_wd(collection_ids=[WD_COLLECTION_ID]):
    
    print("Fetching documents from Watson Discovery")
    documents = []
    
    print("Configuring the WD client")
    authenticator = IAMAuthenticator(WD_API_KEY)
    wd_client = DiscoveryV2(
        version="2023-03-31",
        authenticator=authenticator
    )
    
    print("Setting the WD service URL")
    wd_client.set_service_url(WD_SERVICE_URL)
    
    print("Fetching documents from WD")
    page_id = 0
    retries = 0
    while True:
        try:
            print("Fetching page: " + str(page_id))
            response = wd_client.query(
                project_id=WD_PROJECT_ID,
                collection_ids=collection_ids,
                return_=["text"],
                count=WD_PAGE_SIZE,
                offset=page_id*WD_PAGE_SIZE
            ).get_result()
            if response is None or not isinstance(response, dict):
                print("No query result")
                raise ValueError("No query result")
            if "results" not in response or response["results"] is None or not isinstance(response["results"], list):
                print("No query result 2")
                raise ValueError("No query result")
            results = response["results"]
            if len(results) == 0:
                print("No more results")
                break
            print("Fetched " + str(len(results)) + " documents")
            documents.extend(list(map(lambda result: Document(page_content=result["text"][0],  
                                                              metadata= {"collection_id": WD_COLLECTION_ID, "document_id" : result['document_id']}), results)))
            page_id += 1
        except Exception as error:
            logging.error("Failed to fetch documents from WD", str(error))
            retries += 1
            time.sleep(5)
            if retries > MAX_RETRIES:
                break
            print("Retrying...")
    print("Fetched " + str(len(documents)) + " documents")
    return documents

 

Rastreo web en Watson Discovery

Al crear un proyecto en Watson Discovery, puede programar un rastreo web para obtener información de una URL especificada. Todo lo que necesita hacer es seleccionar Web Crawl al seleccionar la fuente de datos y luego especificar la URL y el cronograma de rastreo.

Pantalla de configuración para el rastreador web Watson Discovery
Captura de pantalla del programador del rastreador web Watson Discovery

Después de eso, puede seguir los pasos que se mencionaron anteriormente para administrar su colección y usar la API para leer los datos de su colección. Para ver más detalles sobre cómo configurar Web Crawl en Watson Discovery, puede ver este video.

Para obtener más información y características, puede consultar la página para desarrolladores de Watson Discovery.

Búsqueda a profundidad

Búsqueda a profundidad es el kit de herramientas de código abierto de IBM para la ingestión. Búsqueda a profundidad aprovecha métodos de IA de última generación para recopilar, convertir, enriquecer y enlazar continuamente grandes colecciones de documentos. Puede usarlo tanto para documentos PDF públicos como exclusivos.

Búsqueda a profundidad convierte documentos PDF no estructurados en archivos JSON estructurados con precisión y facilidad. Le permite automatizar la extracción de conocimientos, así como ajustar sus modelos fundacionales y modelos de lenguaje grandes patentados.

Puede encontrar más información sobre la búsqueda a profundidad aquí.

La búsqueda a profundidad puede ser una buena herramienta interna para leer documentos complejos en lugar de bibliotecas no estructuradas u otras bibliotecas de código abierto. También puede encontrar muy buena documentación en el repositorio con diferentes tipos de ejemplos como cuadernos de Python:

Cuadernos de ejemplo de búsqueda a profundidad

Ingesta de tablas desde archivos PDF

La búsqueda profunda proporciona buenos resultados al extraer tablas de PDF en formato JSON.

Para las pruebas, hemos utilizado un documento PDF parcial del CIPP, que incluye tres páginas, cada una de las cuales muestra datos de tablas. El mejor rendimiento de RAG en este caso se logra utilizando búsqueda a profundidad para extraer tablas en formato JSON y luego convertirlas a HTML para usarlas en Watson Discovery/watsonx Discovery en lugar de usar directamente PDF, convertir PDF a HTML sin búsqueda a profundidad, o solo utilizando JSON de búsqueda a profundidad en Watson Discovery/watsonx Discovery. Descubrimos que Watson Discovery selecciona la respuesta incorrecta de la celda incorrecta de la tabla en algunos casos, pero más rápido, y en el mismo caso, Watson Discovery puede identificar la respuesta exacta dentro de la cuadrícula de la tabla.

IBM Datacap

IBM Datacap es una solución integral para la captura de documentos y datos que ofrece un escaneo, clasificación, reconocimiento, validación y exportación de datos e imágenes de documentos rápido, preciso y rentable. Captura documentos, extrae datos relevantes y los integra en procesos de negocio posteriores.

Datacap adquiere documentos en papel a través de escáneres, impresoras multifunción o dispositivos móviles e importa documentos electrónicos desde sistemas de archivos, fax o servidores de correo electrónico. Mejora la extracción de datos con características de procesamiento de imágenes, como desviar y eliminar líneas, manchas y bordes.

Datacap utiliza el reconocimiento óptico de caracteres (OCR), el reconocimiento inteligente de caracteres (ICR) para la escritura a mano, el reconocimiento óptico de marcas (OMR) para las marcas y la lectura de códigos de barras para extraer datos de manera eficiente.

Para obtener instrucciones detalladas de instalación y uso, consulte la documentación de IBM Datacap.

Herramientas de código abierto

Cargadores de datos de LangChain

LangChain admite diferentes tipos de cargadores de documentos que cargan datos de una fuente como objeto LangChain Document. Un objeto Document es un fragmento de texto y metadatos asociados que se pueden usar fácilmente para fragmentar y recuperar más adelante en el pipeline.

Actualmente, LangChain admite cargadores para cargar un directorio completo o diferentes tipos de archivos, como:

  • CSV
  • HTML
  • JSON
  • Markdown
  • Microsoft Office
  • PDF

Puede usar estos cargadores en pocas líneas en python. Por ejemplo, para cargar un PDF, puede usar el siguiente código:

from langchain_community.document_loaders import PyPDFLoader

loader = PyPDFLoader("example_data/layout-parser-paper.pdf")
pages = loader.load_and_split()

Consulte la documentación de LangChain para ver cómo usar estos cargadores.

Además de los mencionados en el enlace anterior, puede encontrar cargadores adicionales que pueden cargar datos directamente desde aplicaciones específicas, como correo electrónico, Github, Google Drive, etc. Puede encontrar la lista de todos los diferentes cargadores aquí.

En los casos en los que tenga documentos con estructuras, formatos y tablas complejos, puede utilizar los cargadores no estructurados de LangChain. Estos cargadores tras bambalinas utilizan la biblioteca no estructurada, que es una de las mejores bibliotecas para documentos complejos (en diferentes formatos, como PDF, MSWord, Power Point, etc.) y para dividir los documentos en diferentes componentes: LangChain UnstructuredLoader

Cargadores de datos de LlamaIndex

Al igual que LangChain, LlamaIndex también admite diferentes tipos de cargadores. Una de las formas sencillas de cargar datos con LlamaIndex es usar SimpleDirectoryReader. SimpleDirectoryReader admite los siguientes tipos:

  • .csv - valores separados por comas
  • .docx - Microsoft Word
  • .epub: formato de libro electrónico EPUB
  • .hwp - Procesador de textos Hangul
  • .ipynb - Jupyter Notebook
  • .jpeg, .jpg - Imagen JPEG
  • .mbox: archivo de correo electrónico MBOX
  • .md - Markdown
  • .mp3, .mp4 - audio y video
  • .pdf - Formato de documento portátil
  • .png - Gráficos de red portátiles
  • .ppt, .pptm, .pptx - Microsoft PowerPoint

Puede usar SimpleDirectoryLoader con el siguiente fragmento de código:

from llama_index.core import SimpleDirectoryReader

reader = SimpleDirectoryReader(input_dir="path/to/directory")
documents = reader.load_data()

También puede agregar extensiones específicas para leer solo esas extensiones del directorio:

SimpleDirectoryReader(
   input_dir="path/to/directory", required_exts=[".pdf", ".docx"]
 )

Para obtener más detalles sobre cómo usar LlamaIndex Loaders, consulte su documentación.

También de forma similar a Huggingface, puede crear sus propios cargadores personalizados o utilizar los cargadores personalizados de otras personas en llamahub.IA.

Sin embargo, una desventaja de LlamaIndex en comparación con LangChain es que la documentación y el soporte de la comunidad no son tan buenos como LangChain, por lo que depurar su código puede ser más difícil.

No estructurados

En los casos en que esté cargando documentos complejos, también puede usar directamente la biblioteca no estructurada. La biblioteca no estructurada es realmente buena para leer y analizar tablas.

La biblioteca no estructurada también es compatible con los contenedores LangChain y LlamaIndex, por lo que podría ser más fácil usarla para los pipelines de RAG en el futuro, ya que crearán y devolverán automáticamente los objetos Document. Sin embargo, si su proyecto necesita más personalización y desea utilizar directamente la biblioteca no estructurada, puede consultar la siguiente documentación: Unstructured.

Explore más

Obtenga los patrones de tecnología más recientes, arquitecturas de soluciones, y publicaciones de arquitectura de IBM.

  1. Ir al Centro de Arquitectura de IBM
Colaboradores