Publié le
Fireworks

Évaluation de l'Inlining de Fireworks : Forces et Limites dans l'Analyse de PDFs et d'Images

Post image placeholder

Ce post évalue la fonctionnalité d'inlining de documents proposée par Fireworks, qui permet aux utilisateurs de traiter des PDFs et des images en convertissant leur contenu en un format interrogeable. Cette fonctionnalité permet une extraction et une analyse fluides du texte et des données structurées en utilisant des requêtes en langage naturel alimentées par des modèles de langage de grande taille (LLMs).

L'inlining de documents exploite des modèles de texte spécialisés, permettant un raisonnement supérieur par rapport aux modèles vision-langage (VLMs) traditionnels dans les tâches riches en texte. En réduisant le besoin de manipulation manuelle des données, il améliore l'efficacité et permet des interactions avancées avec du contenu multimodal. Pour cette évaluation, j'ai utilisé le modèle Llama (llama-v3p3-70b-instruct) déployé sur Fireworks pour explorer son efficacité avec trois cas pratiques.

Pour plus de détails, consultez mon article de blog sur l'Inlining de Documents de Fireworks.

Environnement d'Évaluation

Pour reproduire cette évaluation, vous aurez besoin de :

  1. Une clé API de Fireworks AI, car l'inlining de documents et l'inférence sont effectués via le fournisseur de LLM Fireworks.
  2. Un environnement Python pour exécuter le script.

Script Python pour l'Inlining de Documents

En suivant l'exemple de Fireworks, un script Python a été développé pour évaluer les capacités d'inlining de documents pour les PDFs et les images via l'API Fireworks. L'API d'inlining prend en charge deux méthodes d'entrée : fournir des URL directes vers des documents (PDFs ou images) ou télécharger des fichiers locaux. Pour cette évaluation, la décision a été prise d'utiliser exclusivement des documents locaux, car cela correspond mieux aux cas d'utilisation prévus de gestion de données privées ou hors ligne.

Le script traite les fichiers locaux en les encodant en tant qu'URLs Base64, les envoie à l'API et permet aux utilisateurs d'interroger le contenu inlined en utilisant des invites en langage naturel. Il prend en charge plusieurs fichiers dans une seule exécution et offre une option pour spécifier un modèle LLM personnalisé, avec la valeur par défaut définie sur "llama-v3p3-70b-instruct".

Pour exécuter le script, lancez-le depuis la ligne de commande en fournissant les chemins des fichiers, une invite de requête et éventuellement un nom de modèle. Par exemple :

python script_name.py file1.pdf file2.pdf "Votre requête ici"

Le script Python complet est fourni ci-dessous.

"""
Script for interacting with the Fireworks API to process files and generate responses based on a user-provided prompt.

Features:
- Supports multiple file types (PDF, PNG, JPG, GIF, TIFF) by encoding them as Base64 URLs.
- Sends the files and prompt to the Fireworks API for processing.
- Allows specifying an optional model name; defaults to "llama-v3p3-70b-instruct".
- Prints the API's response in a structured and user-friendly format.

Usage:
python script_name.py <path_to_file1> [<path_to_file2> ... <path_to_fileN>] <prompt> [<model_name>]

Requirements:
- Set the FIREWORKS_API_KEY environment variable with a valid API key.
- Install the requests library.

Example:
python script_name.py sample1.pdf sample2.pdf "Extract data from these documents." "custom/model/path"
"""

import requests
import json
import os
import sys
import base64

# Fetch the API key from the environment variable
api_key = os.getenv("FIREWORKS_API_KEY")

if not api_key:
    print("Error: FIREWORKS_API_KEY environment variable is not set.")
    sys.exit(1)

# API endpoint
url = "https://api.fireworks.ai/inference/v1/chat/completions"

# Function to encode a file to Base64 data URL based on its type
def encode_file_to_base64_data_url(file_path):
    _, file_extension = os.path.splitext(file_path.lower())

    # Determine MIME type based on file extension
    mime_type = None
    if file_extension == ".pdf":
        mime_type = "application/pdf"
    elif file_extension in [".png"]:
        mime_type = "image/png"
    elif file_extension in [".jpg", ".jpeg"]:
        mime_type = "image/jpeg"
    elif file_extension == ".gif":
        mime_type = "image/gif"
    elif file_extension == ".tiff":
        mime_type = "image/tiff"
    else:
        print(f"Unsupported file extension: {file_extension}")
        sys.exit(1)

    # Read the file and encode it to Base64
    try:
        with open(file_path, "rb") as file:
            base64_data = base64.b64encode(file.read()).decode("utf-8")
        return f"data:{mime_type};base64,{base64_data}#transform=inline"
    except FileNotFoundError:
        print(f"Error: The file '{file_path}' does not exist.")
        sys.exit(1)
    except Exception as e:
        print(f"An error occurred while encoding the file: {e}")
        sys.exit(1)

# Ensure there are at least two arguments (files and prompt)
if len(sys.argv) < 3:
    print("Usage: python script_name.py <path_to_file1> [<path_to_file2> ... <path_to_fileN>] <prompt> [<model_name>]")
    sys.exit(1)

# Separate file paths, prompt, and optional model name
if sys.argv[-1].startswith("accounts/"):
    model_name = sys.argv[-1]
    prompt = sys.argv[-2]
    file_paths = sys.argv[1:-2]
else:
    model_name = "accounts/fireworks/models/llama-v3p3-70b-instruct"
    prompt = sys.argv[-1]
    file_paths = sys.argv[1:-1]

# Validate that at least one file is provided
if not file_paths:
    print("Error: At least one file must be specified.")
    sys.exit(1)

# Print the model being used
print(f"\nUsing model: {model_name}\n")

# Encode all files to Base64 data URLs
data_urls = []
for file_path in file_paths:
    data_urls.append(encode_file_to_base64_data_url(file_path))

# Create messages for each file
file_messages = [
    {
        "type": "image_url",
        "image_url": {
            "url": data_url
        }
    }
    for data_url in data_urls
]

# Payload for the API request
payload = {
    "model": model_name,
    "max_tokens": 16384,
    "top_p": 1,
    "top_k": 40,
    "presence_penalty": 0,
    "frequency_penalty": 0,
    "temperature": 0.6,
    "messages": [
        {
            "role": "user",
            "content": file_messages + [
                {
                    "type": "text",
                    "text": prompt
                }
            ]
        }
    ]
}

# Headers for the API request
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
    "Authorization": f"Bearer {api_key}"
}

try:
    # Print the prompt
    print("\nPrompt:")
    print(f"- {prompt}")

    # Print the files being processed
    print("\nFiles:")
    for file_path in file_paths:
        print(f"- {file_path}")

    # Make the POST request to the API
    response = requests.post(url, headers=headers, data=json.dumps(payload))

    # Raise an HTTPError for bad responses (4xx and 5xx)
    response.raise_for_status()

    # Parse the JSON response
    response_data = response.json()

    # Print formatted output
    print("\nResponse from API:")
    print(f"ID: {response_data.get('id')}")
    print(f"Model: {response_data.get('model')}\n")

    # Print choices header
    print("Response Text:")
    for choice in response_data.get('choices', []):
        print(f"- Finish Reason: {choice.get('finish_reason')}")
        print(f"  Content: \n{choice['message']['content']}\n")

    # Print usage details
    print("Usage:")
    usage = response_data.get('usage', {})
    print(f"- Prompt Tokens: {usage.get('prompt_tokens')}")
    print(f"- Completion Tokens: {usage.get('completion_tokens')}")
    print(f"- Total Tokens: {usage.get('total_tokens')}")
except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Cas d'Évaluation

Cas 1 : Comparaison de Deux Documents PDF

Objectif : Analyser deux articles de recherche au format PDF et identifier les points communs et les différences clés.

Exécution : Le script a été exécuté avec les deux documents PDF stockés localement et l'invite fournie. La commande utilisée était :

python3 inline_fireworks.py data/2408.02479v1.pdf data/2411.00932v1.pdf "Identify the titles of both provided papers and compare their content. Summarize their common points and highlight key differences."

Résultats : La sortie suivante a été générée par l'exécution du script :

The two papers provided are:

1. "From LLMs to LLM-based Agents for Software Engineering: A Survey of Current, Challenges and Future"
2. "LLMs: A Game-Changer for Software Engineers?"

Comparing their content, both papers discuss the application of Large Language Models (LLMs) in software engineering, highlighting their potential to revolutionize the field. They explore the capabilities and limitations of LLMs, as well as their future directions and challenges.

**Common points between the two papers include:**

- The discussion of LLMs' ability to automate tasks such as code generation, testing, and debugging
- The potential of LLMs to improve software development productivity and quality
- The need for human oversight and review of LLM-generated code to ensure accuracy and security
- The importance of addressing ethical concerns, such as bias and intellectual property, in the development and use of LLMs

**Key differences between the two papers include:**

- The first paper focuses specifically on LLM-based agents, which are designed to work autonomously and make decisions, whereas the second paper provides a more general overview of LLMs in software engineering.
- The first paper provides a detailed analysis of the architecture and benchmarks used in LLM-based agents, while the second paper discusses the technical strengths and benefits of LLMs in software engineering, as well as their challenges and future directions.
- The first paper is more focused on the academic and research aspects of LLM-based agents, while the second paper is more geared towards practitioners and industry professionals, providing a more practical perspective on the adoption and use of LLMs in software engineering.

Overall, both papers contribute to the growing body of research on LLMs in software engineering, highlighting their potential to transform the field and improve software development practices. However, they approach the topic from different angles, with the first paper focusing on the technical aspects of LLM-based agents and the second paper providing a more general and practical overview of LLMs in software engineering.

Évaluation : Le modèle a efficacement identifié les titres des deux articles et extrait des comparaisons détaillées de leur contenu. Les résultats ont démontré une bonne compréhension des sujets, mettant en évidence les points communs et les différences de manière exhaustive. Ce cas montre la capacité de Fireworks à analyser du texte structuré et à fournir des comparaisons perspicaces. Cependant, de légères améliorations dans la formulation des points communs et des différences pourraient encore améliorer la lisibilité et la clarté.

Cas 2 : OCR d'Images de Documents

Objectif : Effectuer une OCR sur deux images de documents locales en un seul appel, en extrayant leur contenu et en analysant les différences de mots.

L'évaluation a été réalisée en utilisant deux images de documents stockées localement, montrées ci-dessous :

Première image de document
Figure 1 : Première image de document utilisée pour l'analyse OCR.
Deuxième image de document
Figure 2 : Deuxième image de document utilisée pour l'analyse OCR.

Exécution : Le script a été exécuté avec les deux fichiers image locaux et l'invite fournie. La commande utilisée était :

python3 inline_fireworks.py data/example_01_mistral_exec_01.png data/example_01_mistral_exec_02.png "Identify common and unique words in the two provided files."

Résultats : La sortie suivante a été générée par l'exécution du script :

To identify the common and unique words in the two provided files, let's analyze the lists of Large Language Models (LLMs) mentioned:

### First File:
1. Mistral
2. ChatGPT
3. Clude LLaMA
4. Gemini
5. Falcon

### Second File:
1. Mistral
2. Mistral
3. ChatGPT
4. CLaude
5. LLaMA
6. Gemini/Falcon

### Common Words:
- **Mistral**: Appears in both files.
- **ChatGPT**: Appears in both files.
- **Gemini** and **Falcon**: While presented as a single entity in the second file (Gemini/Falcon), they are individually listed in the first file. Considering the intent, these can be seen as common, albeit presented differently.
- **LLaMA**: Appears in the first file as part of "Clude LLaMA" and separately in the second file. Assuming "Clude LLaMA" refers to the same model as "LLaMA" in the context of these lists, LLaMA can be considered common.

### Unique Words:
- **Clude**: This appears to be a typo or variation in the first file ("Clude LLaMA") and is presented as "CLaude" in the second file. If "CLaude" is considered a distinct model from "Clude LLaMA," then "CLaude" is unique to the second file.

Correcting for the apparent typo and considering the intent behind the naming:
- The first file's "Clude LLaMA" likely refers to "CLaude" and "LLaMA" as separate entities, making "CLaude" a unique mention in the second file when compared to the first file's listing.
- "LLaMA" is common, given it's part of "Clude LLaMA" in the first file and listed separately in the second.

Thus, the unique word, considering corrections for typos and intent, would be "CLaude" as it's explicitly listed that way only in the second file, and there's a duplication of "Mistral" in the second file not present in the first.

Évaluation : Le processus OCR a été efficace, capturant les informations clés et distinguant avec précision les mots communs et uniques.

Cas 3 : Interrogation d'une Image d'Horaire de Bus

Objectif : Poser des questions sur une image contenant un horaire de bus extrait de ici.

L'évaluation a été réalisée en utilisant une image stockée localement d'un horaire de bus, montrée ci-dessous :

Image d'horaire de bus
Figure 3 : L'image de l'horaire de bus utilisée pour l'interrogation.
  • Document : Une image stockée localement d'un horaire de bus
  • Prompt : Une question sur les heures de départ d'un arrêt de bus dans l'horaire du lundi au vendredi.

Exécution : Le script a été exécuté avec le fichier image local et l'invite fournie. La commande utilisée était :

python3 inline_fireworks.py data/whitsunday_bus_timetable.jpg "Based on the attached image, give me departure times at Flametree from Monday to Friday. Simply reply I don't know if you cannot find them in the attached picture."

Résultats : La sortie suivante a été générée par l'exécution du script :

I don't know.

Pour évaluer davantage les performances, le script a été exécuté en utilisant le modèle qwen2p5-72b-instruct avec la commande suivante :

python3 inline_fireworks.py data/whitsunday_bus_timetable.jpg "Based on the attached image, give me departure times from Flametree from Monday to Friday. Simply reply I don't know if you cannot find them in the attached picture." accounts/fireworks/models/qwen2p5-72b-instruct

La sortie est restée la même, indiquant que le problème réside dans l'intégration OCR-contexte plutôt que dans le modèle spécifique utilisé.

Évaluation :
Ce cas met en évidence une limitation dans le traitement des données tabulaires dans les images. La réponse constante 'I don't know' avec les deux modèles suggère que le problème pourrait provenir soit du processus d'inlining, soit des capacités d'extraction de données de l'OCR. Améliorer ces aspects pourrait améliorer la gestion des formats structurés dans les images comme les horaires par Fireworks.

Conclusion

La fonctionnalité d'inlining de documents de Fireworks démontre un fort potentiel pour l'analyse et l'interrogation de PDFs et d'images, offrant des avantages notables en termes de productivité pour les tâches d'extraction et d'analyse de texte. L'évaluation a montré une performance efficace dans le traitement et la comparaison de texte à partir de documents PDF (Cas 1) et l'extraction de contenu à partir d'images de documents (Cas 2), identifiant avec succès les détails clés et générant des sorties significatives.

Cependant, des limitations ont été observées dans l'interprétation des formats de données structurées comme les horaires dans les images (Cas 3), où le modèle a systématiquement échoué à extraire les informations pertinentes, probablement en raison des défis de parsing pendant le processus d'inlining ou de l'OCR. Ces résultats suggèrent que bien que Fireworks soit un outil précieux pour le texte non structuré et semi-structuré, ses capacités dans la gestion des formats structurés comme les tableaux nécessitent un développement supplémentaire. Améliorer ces aspects élargirait considérablement son utilité dans les applications réelles.


Vous avez apprécié ce post ? Vous l'avez trouvé utile ? N'hésitez pas à laisser un commentaire ci-dessous pour partager vos réflexions ou poser des questions. Un compte GitHub est requis pour participer à la discussion.

Continuer la lecture

Articles similaires