Passer au contenu principal
En pratique, il existe trois façons d’utiliser le traitement multiprocessus avec ABBYY FineReader Engine : D’une part, vous pouvez utiliser un objet Engine en définissant la propriété MultiProcessingParams de l’objet Engine sur les valeurs appropriées. ABBYY FineReader Engine prend en charge deux objets différents qui permettent le traitement multiprocessus à partir d’une seule instance d’Engine. Il s’agit de l’objet FRDocument (voir Traitement avec l’objet FRDocument) et de l’objet BatchProcessor (voir Traitement avec Batch Processor). D’autre part, vous pouvez charger plusieurs instances d’Engine en tant que serveurs hors processus au moyen de COM (à l’aide de l’objet OutprocLoader) et utiliser chaque instance dans son propre processus. Voir Traitement à l’aide d’un pool d’Engine.
Veuillez noter que le traitement parallèle nécessite plus de RAM que le traitement séquentiel. La recommandation générale pour une station de travail est de 350 MB * (nombre de cœurs) + 450 MB de RAM et, si vous traitez des documents en arabe ou dans des langues CJK, de 850 MB * (nombre de cœurs) + 750 MB de RAM.

Scénarios d’utilisation

Nous partirons du principe que vous traitez un grand nombre de documents. Mais nous devons également tenir compte des résultats que vous souhaitez obtenir et choisir la meilleure approche pour mettre en œuvre votre tâche. Les différents scénarios à envisager sont les suivants :
  • Conversion de documents multipages comportant un grand nombre de pages. Il s’agit généralement de livres, de rapports longs, etc. Dans ce cas, vous pouvez reconnaître les pages du document en parallèle, puis effectuer la synthèse dans le processus principal et relancer ensuite l’export en parallèle. Vous pouvez également, lorsque vous utilisez un pool d’Engines, traiter simultanément plusieurs documents multipages, mais la consommation de mémoire peut être très importante et même entraîner des erreurs « out of memory ».
  • Conversion d’un grand nombre de documents d’une seule page. C’est le cas lorsque vous traitez des factures, des contrats, des lettres, etc. Le traitement parallèle est le plus simple dans cette situation, car les documents d’une page sont indépendants les uns des autres et ne nécessitent pas de grandes quantités de mémoire en même temps.
  • Traitement d’un grand nombre d’images et recherche des informations nécessaires, ou exploitation des résultats de reconnaissance d’une autre manière. Il est possible que vous n’ayez pas besoin de convertir la plupart d’entre elles dans un format modifiable, de sorte que la vitesse de la synthèse et de l’export n’est pas un enjeu. L’opération exécutée dans plusieurs processus consiste à parcourir les blocs de mise en page et à accéder aux résultats de reconnaissance des blocs de texte.
Si vous souhaitez utiliser le traitement parallèle pour l’export, gardez à l’esprit que cette fonctionnalité est prise en charge uniquement pour l’export au format PDF (sauf en mode TextOnly) et au format PPTX.

Recommandations et restrictions

  • Pour le traitement parallèle de documents multipages, nous recommandons d’utiliser FRDocument. C’est la méthode de multitraitement la plus simple à mettre en œuvre, car vous n’avez pas besoin d’implémenter d’interfaces supplémentaires.
    L’ouverture, le prétraitement, l’analyse et la reconnaissance sont effectués en parallèle ; la synthèse de documents est effectuée séquentiellement dans le processus principal, puis l’export vers les formats PDF (sauf en mode TextOnly) et PPTX est effectué en parallèle.
  • Pour traiter un grand nombre de documents d’une page provenant d’une source (par exemple, un scanner), nous recommandons BatchProcessor.
    L’avantage de cette méthode est qu’elle peut être utilisée lorsque vous ne connaissez pas à l’avance le nombre de documents, que ceux-ci peuvent être de types différents et qu’ils doivent être traités dès leur arrivée. Son inconvénient est qu’elle demande davantage d’efforts d’implémentation : vous devez implémenter des interfaces pour un adaptateur de fichiers et une source d’images personnalisée.
    Toutes les étapes de traitement sont effectuées en parallèle, car dans le cas de documents d’une page, la synthèse de page et la synthèse de documents sont effectuées séparément pour chaque page.
L’export parallèle n’est pas pris en charge dans les scénarios utilisant Batch Processor.
  • Pour effectuer en parallèle le traitement complet d’un grand nombre de documents d’une page, vous pouvez utiliser un pool d’Engines chargés hors processus au moyen de COM. Cette méthode est la plus efficace en termes de vitesse et élimine automatiquement toutes les difficultés liées au multithreading : toutes les opérations sur les objets ABBYY FineReader Engine sont sérialisées au moyen de COM. Mais elle présente certaines limites :
  • en raison de l’utilisation de COM, vous devez enregistrer FREngine.dll ;
  • si votre code est écrit en C++, travailler avec COM demande plus de code répétitif que, par exemple, en C# ;
  • dans ce cas, le traitement s’effectue dans un autre processus, vous ne pouvez donc pas ouvrir d’images à partir de la mémoire, et l’itération des résultats de reconnaissance prend plus de temps, car chaque requête doit être transmise à un autre processus puis renvoyée ;
  • et enfin, charger plusieurs instances d’Engines implique une consommation mémoire plus importante, d’autant plus que, dans ce cas, toutes les étapes de traitement sont effectuées en parallèle et que plusieurs opérations de synthèse peuvent s’exécuter simultanément, ce qui consomme encore plus de mémoire.
  • Pour intercepter et gérer les événements survenus pendant le traitement parallèle, vous pouvez utiliser l’interface IParallelProcessingCallback. Cette interface peut être très utile pour gérer les situations problématiques. Par exemple, lorsqu’une erreur de dépassement du délai d’attente survient, l’interface IParallelProcessingCallback propose plusieurs solutions en fonction des préférences de l’utilisateur. Pour plus d’informations, consultez IParallelProcessingCallback::OnWaitIntervalExceeded.
Les événements survenus pendant le traitement parallèle d’une page sont convertis en événements concernant l’ensemble du document.

Résultats des tests de vitesse

Le tableau ci-dessous présente les résultats des tests de performance.
<br />Documents d’une pageUn document de plusieurs pagesRecherche dans les résultats sans exportation
Traitement séquentiel605187
Traitement avec FRDocument4111757
Traitement avec FRDocument (avec PageFlushingPolicy = PFP_KeepInMemory)5514182
Traitement avec Batch Processor99115294
Traitement à l’aide d’un pool de Engines16510102
La machine de test est équipée d’un processeur Intel® Core™ i5-4440 (3.10 GHz, 4 cœurs physiques) et de 8 Go de RAM ; le nombre de processus exécutés simultanément est de 4. Les performances ont été testées sur 300 images en anglais, avec les paramètres du profil prédéfini DocumentArchiving_Speed. Les valeurs du tableau indiquent le nombre de pages traitées par minute. Dans les scénarios « documents d’une page » et « un document de plusieurs pages », les documents sont exportés au format PDF.

Traitement avec l’objet FRDocument

Le nombre de processus à exécuter est détecté automatiquement en fonction du nombre de cœurs de processeur physiques ou logiques disponibles, du nombre de cœurs de processeur libres autorisés par la licence et du nombre de pages du document. Pour activer le mode multiprocessus, procédez comme suit :
  1. Définissez la valeur de la propriété MultiProcessingMode du sous-objet MultiProcessingParams de l’objet Engine. Le traitement parallèle est utilisé si cette propriété est définie sur MPM_Parallel ou MPM_Auto, et si le nombre de pages du document et le nombre de cœurs de processeur disponibles sont tous deux supérieurs à un.
  2. Réglez le nombre de processus à exécuter à l’aide de la propriété RecognitionProcessesCount et spécifiez les valeurs des autres propriétés si nécessaire.
Après avoir configuré les paramètres du mode multiprocessus, vous pouvez suivre la procédure standard d’utilisation de FRDocument. ABBYY FineReader Engine démarrera automatiquement plusieurs processus de reconnaissance lorsque vous appellerez l’une des méthodes suivantes de l’objet FRDocument : Pour chaque page du document, une nouvelle tâche de traitement est créée, puis affectée à l’un des processus de reconnaissance. Lorsqu’un processus de reconnaissance termine la tâche, il reçoit la tâche de traitement suivante. Cela se poursuit jusqu’à ce que toutes les tâches aient été traitées.
// Créer le document
FREngine.IFRDocument document = engine.CreateFRDocument();
// Ajouter des pages au document
for( int index = 0; index < filesNumber; index++ ) {
    string imagePath = filePaths[index];
    document.AddImageFile( imagePath, null, null );
}
// Configurer les paramètres du multiprocessus
engine.MultiProcessingParams.MultiProcessingMode = FREngine.MultiProcessingModeEnum.MPM_Parallel;
engine.MultiProcessingParams.RecognitionProcessesCount = coresNumber;
// Créer et configurer les paramètres de traitement du document
FREngine.IDocumentProcessingParams documentProcessingParams = engine.CreateDocumentProcessingParams();
...
// Traiter le document
document.Process( documentProcessingParams );
// Synthétiser et exporter le document comme d’habitude, utiliser les résultats, etc.
...
Le package de distribution ABBYY FineReader Engine inclut l’outil de démonstration MultiProcessingRecognition, qui montre le gain de vitesse obtenu grâce à l’utilisation de la reconnaissance multiprocessus avec l’objet FRDocument et contient une implémentation que vous pouvez utiliser comme point de départ pour développer votre propre application.

Traitement avec Batch Processor

Lorsque Batch Processor est initialisé, des processus de reconnaissance asynchrones sont démarrés et configurés. Le processeur récupère ensuite des fichiers image depuis une source d’images personnalisée. Pour chaque page du fichier image, une nouvelle tâche de traitement est créée, puis transmise à l’un des processus de reconnaissance. Si toutes les tâches d’un fichier ont été envoyées au traitement, mais que tous les processus de reconnaissance ne sont pas occupés, le fichier image suivant de la file d’attente d’images de la source est récupéré et envoyé au traitement. Cette opération se poursuit jusqu’à ce que la première page d’image ait été convertie et renvoyée à l’utilisateur. Les pages sont renvoyées à l’utilisateur dans l’ordre où elles ont été récupérées depuis la source d’images. Pour mettre en place le traitement multiprocessus avec Batch Processor, procédez comme suit :
  1. Implémentez les interfaces IImageSource et IFileAdapter, qui fournissent l’accès à la source d’images et aux fichiers qu’elle contient.
  2. [facultatif] Implémentez l’interface IAsyncProcessingCallback pour gérer le traitement. Les méthodes de cette interface vous permettent de gérer les erreurs et/ou d’annuler le traitement.
  3. [facultatif] Configurez le traitement multiprocessus à l’aide du sous-objet MultiProcessingParams de l’objet Engine. Veuillez noter qu’il n’est pas nécessaire de définir la propriété MultiProcessingMode, car le traitement parallèle est utilisé par défaut si vous travaillez avec Batch Processor. Réglez le nombre de processus à exécuter à l’aide de la propriété RecognitionProcessesCount et spécifiez les valeurs des autres propriétés, si nécessaire.
  4. Appelez la méthode CreateBatchProcessor de l’objet Engine pour obtenir l’objet BatchProcessor.
  5. Appelez la méthode Start de cet objet pour initialiser le processeur et démarrer les processus de reconnaissance asynchrones. Vous pouvez spécifier la source d’images, transmettre les références à l’interface IAsyncProcessingCallback et aux objets de paramètres dans l’appel de cette méthode.
  6. Appelez la méthode GetNextProcessedPage dans une boucle jusqu’à ce qu’elle renvoie 0, ce qui signifie qu’il n’y a plus d’images dans la source et que toutes les images traitées ont été renvoyées à l’utilisateur.
La page renvoyée par la méthode GetNextProcessedPage existe jusqu’à l’appel suivant de cette méthode. Par conséquent, si vous souhaitez enregistrer cette page, vous devez la sauvegarder à l’aide des méthodes de l’objet FRPage ou l’ajouter à un document existant à l’aide de la méthode IFRDocument::AddPage AVANT l’appel suivant de la méthode GetNextProcessedPage.
// Créer Batch Processor
FREngine.IBatchProcessor batchProcessor = engine.CreateBatchProcessor();
// Configurer les paramètres de traitement multiprocessus
engine.MultiProcessingParams.RecognitionProcessesCount = coresNumber;
// Initialiser le processeur
FREngine.IImageSource imageSource = new CImageSource; // la classe est implémentée par l'utilisateur
batchProcessor.Start( imageSource, null, null, null );
// Démarrer le traitement
while( true ) {
 FREngine.IFRPage page = batchProcessor.GetNextProcessedPage();
 if( page == null ) {
  break; // il n'y a plus de pages, fin du traitement
 }
 // faire quelque chose avec la page
 page.Synthesize( null );
 page.Export("D:\\sample.pdf", FREngine.FileExportFormatEnum.FEF_PDF, null);
}
Le package de distribution d’ABBYY FineReader Engine inclut l’exemple BatchProcessing, qui montre comment utiliser Batch Processor, ainsi que l’outil de démonstration BatchProcessingRecognition, qui montre le gain de vitesse obtenu lors de l’utilisation de la reconnaissance multiprocessus avec Batch Processor.

Traitement à l’aide d’un pool d’instances Engines

Dans ce scénario multiprocessus, vous utilisez plusieurs instances d’Engine chargées hors processus. À l’intérieur de chaque thread de travail, la procédure peut être quasiment la même que pour un traitement dans un seul thread. Il est toutefois recommandé d’implémenter une source d’images personnalisée qui répartira les images entre les threads, à l’aide d’un objet de synchronisation afin de garantir que chaque image n’est traitée qu’une seule fois. Pour charger l’objet Engine hors processus, utilisez l’objet OutprocLoader, qui implémente l’interface IEngineLoader. Lors de son utilisation avec des comptes spécifiques, des autorisations peuvent être requises pour exécuter OutprocLoader avec ces comptes.
// Pour chaque thread, créez un objet OutprocLoader distinct et chargez une instance d’Engine
IEngineLoader engineLoader = new FREngine.OutprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, LicensePath, LicensePassword, "", "", false );
// Nous avons obtenu Engine dans un processus distinct
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload(); // Nous pouvons le décharger lorsqu’il n’est plus nécessaire
 engineLoader = null;
 GC.Collect();
 GC.WaitForPendingFinalizers();
}
En outre, vous pouvez gérer la priorité d’un processus hôte et contrôler s’il est actif à l’aide de l’interface IHostProcessControl.
  • Les autorisations des comptes peuvent être configurées à l’aide de l’utilitaire DCOM Config (saisissez DCOMCNFG sur la ligne de commande ou sélectionnez Control Panel > Administrative Tools > Component Services). Dans l’arborescence de la console, localisez le dossier Component Services > Computers > My Computer > DCOM Config, cliquez avec le bouton droit sur ABBYY FineReader Engine 12.5 Loader (Local Server), puis cliquez sur Properties. Une boîte de dialogue s’ouvre. Cliquez sur l’onglet Security. Sous Launch Permissions, cliquez sur Customize, puis sur Edit pour spécifier les comptes autorisés à lancer l’application.
Notez que sur un système d’exploitation 64 bits, l’application DCOM enregistrée est disponible dans la console MMC 32 bits, qui peut être exécutée à l’aide de la ligne de commande suivante :
"mmc comexp.msc /32"
  • Pour enregistrer FREngine.dll lors de l’installation de votre application sur l’ordinateur d’un utilisateur final, utilisez l’utilitaire regsvr32. Si vous utilisez un système d’exploitation 64 bits, la version 64 bits de regsvr32 s’exécute par défaut. Utilisez la commande suivante :
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"
  • Si vous implémentez Engine en tant que serveur hors processus, spécifiez le mode séquentiel de traitement des documents en définissant la propriété MultiProcessingMode de l’objet MultiProcessingParams sur MPM_Sequential.
Le package de distribution d’ABBYY FineReader Engine inclut l’exemple EnginesPool, qui montre le gain de performances obtenu lors de l’utilisation d’un pool d’instances Engines et fournit une implémentation prête à l’emploi pouvant servir de point de départ à votre propre application. Consultez le code source de cet exemple pour en savoir plus sur l’implémentation d’une source d’images personnalisée, la gestion des exceptions et le contrôle de l’utilisation des cœurs CPU.

Voir aussi

FRDocument BatchProcessor MultiProcessingParams Parcourir les pages d’un document Différentes manières de charger l’objet Engine Utiliser ABBYY FineReader Engine dans des applications serveur multithreadées