feat: support ocr for images using llm#374
Conversation
| $fileType = $file->getMimeType(); | ||
| if (!str_starts_with($fileType, 'image/')) { | ||
| throw new UserFacingProcessingException('Only supports image file types' . $fileType, userFacingMessage: $this->l->t('Only supports image file types')); | ||
| } | ||
| if ($this->openAiAPIService->isUsingOpenAi()) { | ||
| $validFileTypes = [ | ||
| 'image/jpeg', | ||
| 'image/png', | ||
| 'image/gif', | ||
| 'image/webp', | ||
| ]; |
There was a problem hiding this comment.
would be nice if we can also support pdfs through pdf -> jpg conversion. The rest of the path would remain the same.
a small snippet that uses imagick to do this (which preview generator of NC also uses with the imagick php extension):
(ai generated)
private function pdfToJpegFiles(string $pdfPath, int $dpi = 200, int $maxPages = 500): array {
if (!extension_loaded('imagick')) {
throw new \RuntimeException('Imagick extension not available');
}
if (empty(\Imagick::queryFormats('PDF'))) {
throw new \RuntimeException('Imagick has no PDF support (Ghostscript missing or blocked by policy.xml)');
}
$probe = new \Imagick();
$probe->pingImage($pdfPath);
$pageCount = min($probe->getNumberImages(), $maxPages);
$probe->clear();
$paths = [];
for ($i = 0; $i < $pageCount; $i++) {
$im = new \Imagick();
$im->setResolution($dpi, $dpi); // before readImage
$im->readImage($pdfPath . '[' . $i . ']');
$im->setImageBackgroundColor('white');
$im = $im->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN); // JPEG has no alpha
$im->setImageFormat('jpeg');
$im->setImageCompressionQuality(85);
$tmpPath = $this->tempManager->getTemporaryFile('.jpg');
$im->writeImage($tmpPath);
$im->clear();
$paths[] = $tmpPath;
}
return $paths;
}for the 500 MB php worker memory limit, we can impose a max limit of 500 pages of pdf in the task type as it is now and convert them to jpgs like above storing them in the disk.
after this the chat completion requests could run with a batch size of 50 converting 50 images to base64 base64_encode(file_get_contents($path), run the OCR and collect the texts.
wdyt?
There was a problem hiding this comment.
I added some code Imagick isn't preinstalled in julius's docker so you'll need to install it manually /usr/local/bin/install-php-extensions imagick (run that in the docker container)
I kept the batch size a lot smaller than this with 5 as that was actually faster than a larger batch size. Honestly it might be worth it to not batch at all as the accuracy goes up with smaller batches at only a very small cost in time (revert the newest commit). Most of the tokens are used by the image anyway.
| Batch Size | Time (From one attempt) |
|---|---|
| 1 | 2:29 |
| 2 | 2:02 |
| 5 | 1:54 |
| 50 | 2:02 |
wdyt?
Signed-off-by: Lukas Schaefer <lukas@lschaefer.xyz>
eeddbd5 to
ab774bc
Compare
Signed-off-by: Lukas Schaefer <lukas@lschaefer.xyz>
Signed-off-by: Lukas Schaefer <lukas@lschaefer.xyz>
|
Damn I didn't see this PR and did it again (without PDF support). Can you check the |
No description provided.