Créez un pipeline de bout en bout pour le prétraitement des données multimodales sur AI Search Open Platform afin d'analyser les documents et les images, de découper le contenu et de générer des embeddings de texte.
Cas d'utilisation
Le pipeline de prétraitement des données multimodales traite les documents non structurés et les images via cinq services : analyse de documents, analyse d'images, découpage de documents, embedding de texte et embedding de texte clairsemé. Tous les services sont appelés via l'API AI Search Open Platform. La facturation est basée sur l'utilisation réelle.
Prérequis
AI Search Open Platform est activé. Activer le service.
-
Votre endpoint API et votre clé API sont prêts. Interroger l'endpoint du service, Gérer la clé API.
Vous pouvez appeler les services via Internet ou par le biais d'un VPC. Les appels VPC inter-régions sont pris en charge dans les régions Chine (Shanghai), Chine (Hangzhou), Chine (Shenzhen), Chine (Pékin), Chine (Zhangjiakou) et Chine (Qingdao).
Créer un pipeline de prétraitement des données multimodales
AI Search Open Platform propose quatre frameworks de développement :
SDK Java
SDK Python
LangChain : sélectionnez cette option si votre activité utilise déjà le framework LangChain.
LlamaIndex : sélectionnez cette option si votre activité utilise déjà le framework LlamaIndex.
Étape 1 : Sélectionner les services et télécharger le code
Cette procédure utilise le SDK Python pour créer un pipeline de prétraitement des données multimodales.
Connectez-vous à la console AI Search Open Platform.
-
Sélectionnez la région Chine (Shanghai), basculez vers AI Search Open Platform, puis accédez à l'espace de travail cible.
RemarqueAI Search Open Platform est disponible uniquement dans les régions Chine (Shanghai) et Allemagne (Francfort).
Les utilisateurs des régions Chine (Hangzhou), Chine (Shenzhen), Chine (Pékin), Chine (Zhangjiakou) et Chine (Qingdao) peuvent utiliser un endpoint VPC pour appeler les services AI Search Open Platform entre différentes régions.
Dans le volet de navigation de gauche, sélectionnez Scene Center. Recherchez Multimodal Data Preprocessing - Data Parsing and Vectorization et cliquez sur Enter.
-
Dans la liste déroulante, sélectionnez les services requis. Vous pouvez consulter les informations détaillées de chaque service sur la page Service Details.
RemarqueChaque service nécessite un ID de service (
service_id). Par exemple, l'ID du service d'analyse de documents estops-document-analyze-001.Le
service_iddans le code généré se met à jour automatiquement lorsque vous changez de service. Vous pouvez également modifier manuellement leservice_idaprès avoir téléchargé le code.
Étape
Description
Analyse du contenu des documents
Service d'analyse du contenu des documents (
ops-document-analyze-001) : extrait les structures logiques telles que les titres et les paragraphes des documents non structurés (texte, tableaux et images) et renvoie un contenu structuré.Analyse du contenu des images
-
Service de compréhension du contenu des images (
ops-image-analyze-vlm-001) : utilise des LLM multimodaux pour analyser le contenu des images et reconnaître le texte afin de permettre la recherche d'images et la réponse aux questions. -
Service de reconnaissance de texte dans les images (
ops-image-analyze-ocr-001) : utilise l'OCR pour reconnaître le texte dans les images afin de permettre la recherche et la réponse aux questions.
Découpage des documents
Service de découpage des documents (
ops-document-split-001) : divise les données structurées aux formats HTML, Markdown et TXT par paragraphe, sémantique ou règles personnalisées. Extrait également le code, les images et les tableaux du texte enrichi.Embedding de texte
-
Service d'embedding de texte OpenSearch-001 (
ops-text-embedding-001) : prend en charge plus de 40 langues. Entrée maximale : 300 tokens. Sortie : vecteurs de 1 536 dimensions. -
Service d'embedding de texte général OpenSearch-002 (
ops-text-embedding-002) : prend en charge plus de 100 langues. Entrée maximale : 8 192 tokens. Sortie : vecteurs de 1 024 dimensions. -
Service d'embedding de texte OpenSearch-Chinois-001 (
ops-text-embedding-zh-001) : spécifique au chinois. Entrée maximale : 1 024 tokens. Sortie : vecteurs de 768 dimensions. -
Service d'embedding de texte OpenSearch-Anglais-001 (
ops-text-embedding-en-001) : spécifique à l'anglais. Entrée maximale : 512 tokens. Sortie : vecteurs de 768 dimensions.
Embedding de texte clairsemé
Convertit le texte en représentations vectorielles clairsemées. Les vecteurs clairsemés nécessitent moins d'espace de stockage et capturent les mots-clés ainsi que les fréquences des termes. Combinez-les avec des vecteurs denses pour une recherche hybride afin d'améliorer la récupération.
Service d'embedding de texte clairsemé OpenSearch (
ops-text-sparse-embedding-001) : prend en charge plus de 100 langues. Entrée maximale : 8 192 tokens.
Après avoir sélectionné les services, cliquez sur After the configuration is completed, enter the code query pour afficher et télécharger le code. Le tableau suivant décrit le flux d'exécution du pipeline de prétraitement des données.
|
Fonction |
Description |
|
Gère le traitement des documents, y compris l'analyse des documents/images, le découpage des documents et l'embedding de texte. |
La fonction principale
|
Sous Code Query, sélectionnez Document Parsing and Vectorization. Cliquez sur Copy Code ou Download File pour enregistrer le code localement.
Étape 2 : Configurer l'environnement et tester le pipeline
Configurez les paramètres suivants après avoir téléchargé le code.
|
Catégorie |
Paramètre |
Description |
|
AI Search Open Platform |
api_key |
La clé API pour l'authentification. Gérer les clés API. |
|
aisearch_endpoint |
L'endpoint API. Interroger l'endpoint du service. Remarque
Supprimez le préfixe Vous pouvez appeler l'API via Internet ou par le biais d'un VPC. |
|
|
workspace_name |
Le nom de votre espace de travail dans AI Search Open Platform. |
|
|
service_id |
L'ID du service. Utilisez
|
Exécutez le code avec Python 3.8.1 ou une version ultérieure pour vérifier les résultats.
Exemple de sortie issu du prétraitement du document Présentation d'AI Search Open Platform :
C:\Users\issuser\PycharmProjects\pythonProject630Demo\.venv\Scripts\python.exe C:\Users\issuser\PycharmProjects\pythonProject3\.venv\Lib\site-packages\alibabacloud_searchplat2...
document_analyze task_id:f6dd92de-01e4-46a2-96c4-b80e7b120239
document_analyze done
document-split done, chunks count: 6 rich text count:9
image analyze :https://img.alicdn.com/imgextra/i2/O1CN01bYc1m81RrcSAyOjMu_!!6000000002165-54-tps-60-60.apng
https://img.alicdn.com/imgextra/i2/O1CN01bYc1m81RrcSAyOjMu_!!6000000002165-54-tps-60-60.apng is unanalysable.
image analyze :https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/3873436171/p802381.png
image analyze :https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/0517992271/p821030.png
image analyze ://gw.alicdn.com/tfs/TB16xwdSXXXXXa.aXXXXXXXXXXX-65-70.gif
https://gw.alicdn.com/tfs/TB16xwdSXXXXXa.aXXXXXXXXXXX-65-70.gif is unanalysable.
image analyze ://img.alicdn.com/tfs/TB1..50QpXXXXX7XpXXXXXXXXXX-40-40.png
image analyze :https://img.alicdn.com/tfs/TB1UdKEM6TpK1RjSZKPXXa3UpXa-256-256.png
image analyze :https://img.alicdn.com/tfs/TB1A0dINW6qK1RjSZFmXXX0PFXa-258-258.jpg
image analyze ://gw.alicdn.com/tfs/TB16xwdSXXXXXa.aXXXXXXXXXXX-65-70.gif
https://gw.alicdn.com/tfs/TB16xwdSXXXXXa.aXXXXXXXXXXX-65-70.gif is unanalysable.
image analyze ://img.alicdn.com/tfs/TB1..50QpXXXXX7XpXXXXXXXXXX-40-40.png
text-embedding done.
Process finished with exit code 0
Code complet du pipeline :
# Multimodal data processing pipeline
# Requirements:
# Python version: 3.8.1 or later
# Package requirements:
# pip install alibabacloud_searchplat20240529
# AI Search Open Platform configuration
aisearch_endpoint = "xxx.platform-cn-shanghai.opensearch.aliyuncs.com"
api_key = "OS-xxx"
workspace_name = "default"
service_id_config = {"document_analyze": "ops-document-analyze-001",
"split": "ops-document-split-001",
"text_embedding": "ops-text-embedding-001",
"text_sparse_embedding": "ops-text-sparse-embedding-001",
"image_analyze": "ops-image-analyze-ocr-001"}
# Input document URL. The example document is the introduction to AI Search Open Platform.
document_url = "https://www.alibabacloud.com/help/zh/open-search/search-platform/product-overview/introduction-to-search-platform?spm=a2c4g.11186623.0.0.7ab93526WDzQ8z"
import asyncio
from operator import attrgetter
from typing import List
from Tea.exceptions import TeaException, RetryError
from alibabacloud_tea_openapi.models import Config
from alibabacloud_searchplat20240529.client import Client
from alibabacloud_searchplat20240529.models import GetDocumentSplitRequest, CreateDocumentAnalyzeTaskRequest, \
CreateDocumentAnalyzeTaskRequestDocument, GetDocumentAnalyzeTaskStatusRequest, \
GetDocumentSplitRequestDocument, GetTextEmbeddingRequest, GetTextEmbeddingResponseBodyResultEmbeddings, \
GetTextSparseEmbeddingRequest, GetTextSparseEmbeddingResponseBodyResultSparseEmbeddings, \
GetImageAnalyzeTaskStatusResponse, CreateImageAnalyzeTaskRequest, GetImageAnalyzeTaskStatusRequest, \
CreateImageAnalyzeTaskRequestDocument, CreateImageAnalyzeTaskResponse
async def poll_doc_analyze_task_result(ops_client, task_id, service_id, interval=5):
while True:
request = GetDocumentAnalyzeTaskStatusRequest(task_id=task_id)
response = await ops_client.get_document_analyze_task_status_async(workspace_name, service_id, request)
status = response.body.result.status
if status == "PENDING":
await asyncio.sleep(interval)
elif status == "SUCCESS":
return response
else:
print("error: " + response.body.result.error)
raise Exception("document analyze task failed")
def is_analyzable_url(url:str):
if not url:
return False
image_extensions = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff'}
return url.lower().endswith(tuple(image_extensions))
async def image_analyze(ops_client, url):
try:
print("image analyze :" + url)
if url.startswith("//"):
url = "https:" + url
if not is_analyzable_url(url):
print(url + " is unanalysable.")
return url
image_analyze_service_id = service_id_config["image_analyze"]
document = CreateImageAnalyzeTaskRequestDocument(
url=url,
)
request = CreateImageAnalyzeTaskRequest(document=document)
response: CreateImageAnalyzeTaskResponse = ops_client.create_image_analyze_task(workspace_name, image_analyze_service_id, request)
task_id = response.body.result.task_id
while True:
request = GetImageAnalyzeTaskStatusRequest(task_id=task_id)
response: GetImageAnalyzeTaskStatusResponse = ops_client.get_image_analyze_task_status(workspace_name, image_analyze_service_id, request)
status = response.body.result.status
if status == "PENDING":
await asyncio.sleep(5)
elif status == "SUCCESS":
return url + response.body.result.data.content
else:
print("image analyze error: " + response.body.result.error)
return url
except Exception as e:
print(f"image analyze Exception : {e}")
def chunk_list(lst, chunk_size):
for i in range(0, len(lst), chunk_size):
yield lst[i:i + chunk_size]
async def document_pipeline_execute(document_url: str = None, document_base64: str = None, file_name: str = None):
# Create an AI Search Open Platform client.
config = Config(bearer_token=api_key,endpoint=aisearch_endpoint,protocol="http")
ops_client = Client(config=config)
# Step 1: Document/Image parsing
document_analyze_request = CreateDocumentAnalyzeTaskRequest(document=CreateDocumentAnalyzeTaskRequestDocument(url=document_url, content=document_base64,file_name=file_name, file_type='html'))
document_analyze_response = await ops_client.create_document_analyze_task_async(workspace_name=workspace_name,service_id=service_id_config["document_analyze"],request=document_analyze_request)
print("document_analyze task_id:" + document_analyze_response.body.result.task_id)
extraction_result = await poll_doc_analyze_task_result(ops_client, document_analyze_response.body.result.task_id, service_id_config["document_analyze"])
print("document_analyze done")
document_content = extraction_result.body.result.data.content
content_type = extraction_result.body.result.data.content_type
# Step 2: Document chunking
document_split_request = GetDocumentSplitRequest(
GetDocumentSplitRequestDocument(content=document_content, content_type=content_type))
document_split_result = await ops_client.get_document_split_async(workspace_name, service_id_config["split"],
document_split_request)
print("document-split done, chunks count: " + str(len(document_split_result.body.result.chunks))
+ " rich text count:" + str(len(document_split_result.body.result.rich_texts)))
# Step 3: Text embedding
# Extract chunking results. For image chunks, the image parsing service extracts text content.
doc_list = ([{"id": chunk.meta.get("id"), "content": chunk.content} for chunk in document_split_result.body.result.chunks]
+ [{"id": chunk.meta.get("id"), "content": chunk.content} for chunk in document_split_result.body.result.rich_texts if chunk.meta.get("type") != "image"]
+ [{"id": chunk.meta.get("id"), "content": await image_analyze(ops_client,chunk.content)} for chunk in document_split_result.body.result.rich_texts if chunk.meta.get("type") == "image"]
)
# A maximum of 32 embeddings can be calculated per request.
chunk_size = 32
all_text_embeddings: List[GetTextEmbeddingResponseBodyResultEmbeddings] = []
for chunk in chunk_list([text["content"] for text in doc_list], chunk_size):
response = await ops_client.get_text_embedding_async(workspace_name,service_id_config["text_embedding"],GetTextEmbeddingRequest(chunk))
all_text_embeddings.extend(response.body.result.embeddings)
all_text_sparse_embeddings: List[GetTextSparseEmbeddingResponseBodyResultSparseEmbeddings] = []
for chunk in chunk_list([text["content"] for text in doc_list], chunk_size):
response = await ops_client.get_text_sparse_embedding_async(workspace_name,service_id_config["text_sparse_embedding"],GetTextSparseEmbeddingRequest(chunk,input_type="document",return_token=True))
all_text_sparse_embeddings.extend(response.body.result.sparse_embeddings)
for i in range(len(doc_list)):
doc_list[i]["embedding"] = all_text_embeddings[i].embedding
doc_list[i]["sparse_embedding"] = all_text_sparse_embeddings[i].embedding
print("text-embedding done.")
if __name__ == "__main__":
# Run the asynchronous task.
# import nest_asyncio # Uncomment the following two lines if you run this in a Jupyter notebook.
# nest_asyncio.apply() # Uncomment the following two lines if you run this in a Jupyter notebook.
asyncio.run(document_pipeline_execute(document_url))
# asyncio.run(document_pipeline_execute(document_base64="eHh4eHh4eHg...", file_name="attention.pdf")) # Alternative method of calling