Skip to content

Commit ba57686

Browse files
feat: Better error handling for absence of shared libraries
1 parent f58107c commit ba57686

File tree

15 files changed

+236
-125
lines changed

15 files changed

+236
-125
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"php": "^8.1",
1717
"ext-ffi": "*",
1818
"codewithkyrian/jinja-php": "^1.0",
19-
"codewithkyrian/transformers-libsloader": "^1.0",
19+
"codewithkyrian/transformers-libsloader": "^2.0",
2020
"imagine/imagine": "^1.3",
2121
"rokka/imagine-vips": "^0.31.0",
2222
"rindow/rindow-math-matrix": "^2.0",

examples/images/multitask.png

355 KB
Loading
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Codewithkyrian\Transformers\Pipelines;
6+
7+
use Codewithkyrian\Transformers\Models\Auto\AutoModel;
8+
use Codewithkyrian\Transformers\Processors\AutoProcessor;
9+
use Codewithkyrian\Transformers\Utils\Image;
10+
11+
require_once './bootstrap.php';
12+
13+
ini_set('memory_limit', '-1');
14+
15+
$processor = AutoProcessor::fromPretrained('Xenova/yolov9-c_all');
16+
$model = AutoModel::fromPretrained('Xenova/yolov9-c_all');
17+
18+
$image = Image::read(__DIR__.'/../images/multitask.png');
19+
20+
$inputs = $processor($image);
21+
22+
['outputs' => $outputs] = $model($inputs);
23+
24+
$boxes = array_map(function ($args) use ($inputs, $model): ?array {
25+
[$xmin, $ymin, $xmax, $ymax, $score, $id] = $args;
26+
27+
if ($score < 0.11) return null;
28+
29+
return [
30+
'xmin' => $xmin,
31+
'ymin' => $ymin,
32+
'xmax' => $xmax,
33+
'ymax' => $ymax,
34+
'score' => $score,
35+
'label' => $model->config['id2label'][$id] ?? 'unknown',
36+
];
37+
}, $outputs->toArray());
38+
39+
$boxes = array_filter($boxes);
40+
41+
$fontSize = 10;
42+
$fontScalingFactor = 0.75;
43+
$fontFile = '/Users/Kyrian/Library/Fonts/JosefinSans-Bold.ttf';
44+
$labelBoxHeight = $fontSize * 2 * $fontScalingFactor;
45+
$colors = array_map(fn () => sprintf('#%06x', mt_rand(0, 0xFFFFFF)), range(0, count($boxes) - 1));
46+
47+
foreach ($boxes as $box) {
48+
$detectionLabel = $box['label'].' '.round($box['score'], 2);
49+
$color = $colors[array_search($box, $boxes)];
50+
51+
$image = $image
52+
->drawRectangle($box['xmin'], $box['ymin'], $box['xmax'], $box['ymax'], $color, thickness: 2)
53+
->drawRectangle(
54+
xMin: $box['xmin'],
55+
yMin: max($box['ymin'] - $labelBoxHeight, 0),
56+
xMax: $box['xmin'] + (strlen($detectionLabel) * $fontSize * $fontScalingFactor),
57+
yMax: max($box['ymin'], $labelBoxHeight),
58+
color: $color,
59+
fill: true,
60+
thickness: 2
61+
)
62+
->drawText(
63+
text: $detectionLabel,
64+
xPos: $box['xmin'] + 5,
65+
yPos: max($box['ymin'] - $labelBoxHeight, 0),
66+
fontFile: $fontFile,
67+
fontSize: $fontSize,
68+
color: 'FFFFFF'
69+
);
70+
}
71+
72+
$image->save(__DIR__.'/../images/corgi-detected.jpg');

examples/pipelines/custom-object-detection.php

Lines changed: 0 additions & 60 deletions
This file was deleted.

examples/pipelines/object-detection.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
$detector = pipeline('object-detection', 'Xenova/detr-resnet-50');
1515

16-
$img = __DIR__ . '/../images/cats.jpg';
16+
$img = __DIR__.'/../images/cats.jpg';
1717

1818
$output = $detector($img, threshold: 0.9);
1919

@@ -23,8 +23,8 @@
2323
//
2424
//foreach ($output as $item) {
2525
// $box = $item['box'];
26-
// $image->drawRectangle($box['xmin'], $box['ymin'], $box['xmax'], $box['ymax'], '0099FF', thickness: 2);
27-
// $image->drawText($item['label'], $box['xmin'], max($box['ymin'] - 5, 0), '/Users/Kyrian/Library/Fonts/JosefinSans-Bold.ttf', 14, '0099FF');
26+
// $image = $image->drawRectangle($box['xmin'], $box['ymin'], $box['xmax'], $box['ymax'], '0099FF', thickness: 2);
27+
// $image = $image->drawText($item['label'], $box['xmin'], max($box['ymin'] - 5, 0), '/Users/Kyrian/Library/Fonts/JosefinSans-Bold.ttf', 14, '0099FF');
2828
//}
2929
//
3030
//$image->save(__DIR__ . '/../images/cats-detection.jpg');

libs/VERSIONS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
DOWNLOADER=1.0.0
1+
DOWNLOADER=2.0.0
22
OPENBLAS=0.3.27
33
RINDOW_MATLIB=1.0.1
44
ONNXRUNTIME=1.17.0

src/FFI/FastTransformersUtils.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Codewithkyrian\TransformersLibrariesDownloader\Libraries;
1010
use FFI;
1111
use FFI\CData;
12+
use RuntimeException;
1213

1314
class FastTransformersUtils
1415
{
@@ -17,13 +18,22 @@ class FastTransformersUtils
1718
private static function ffi(): FFI
1819
{
1920
if (!isset(self::$ffi)) {
21+
self::validateLibrary();
22+
2023
$headerCode = file_get_contents(Libraries::FastTransformersUtils->headerFile(Transformers::$libsDir));
2124
self::$ffi = FFI::cdef($headerCode, Libraries::FastTransformersUtils->libFile(Transformers::$libsDir));
2225
}
2326

2427
return self::$ffi;
2528
}
2629

30+
private static function validateLibrary(): void
31+
{
32+
if (!Libraries::FastTransformersUtils->exists(Transformers::$libsDir)) {
33+
throw new RuntimeException('FastTransformersUtils library not found. Please run "./vendor/bin/transformers install" to install all dependencies.');
34+
}
35+
}
36+
2737
public static function new($type, bool $owned = true, bool $persistent = false): ?CData
2838
{
2939
return self::ffi()->new($type, $owned, $persistent);

src/FFI/OnnxRuntime.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,22 @@ class OnnxRuntime
1616
public static function ffi(): FFI
1717
{
1818
if (!isset(self::$ffi)) {
19+
self::validateLibrary();
20+
1921
$headerCode = file_get_contents(Libraries::OnnxRuntime->headerFile(Transformers::$libsDir));
2022
self::$ffi = FFI::cdef($headerCode, Libraries::OnnxRuntime->libFile(Transformers::$libsDir));
2123
}
2224

2325
return self::$ffi;
2426
}
2527

28+
private static function validateLibrary(): void
29+
{
30+
if (!Libraries::OnnxRuntime->exists(Transformers::$libsDir)) {
31+
throw new RuntimeException("OnnxRuntime library not found. Please run \033[32m`./vendor/bin/transformers install`\033[39m to install all dependencies.");
32+
}
33+
}
34+
2635
public static function api(): mixed
2736
{
2837
if (!isset(self::$api)) {

src/FFI/Samplerate.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,22 @@ class Samplerate
1818
private static function ffi(): FFI
1919
{
2020
if (!isset(self::$ffi)) {
21+
self::validateLibrary();
22+
2123
$headerCode = file_get_contents(Libraries::Samplerate->headerFile(Transformers::$libsDir));
2224
self::$ffi = FFI::cdef($headerCode, Libraries::Samplerate->libFile(Transformers::$libsDir));
2325
}
2426

2527
return self::$ffi;
2628
}
2729

30+
private static function validateLibrary(): void
31+
{
32+
if (!Libraries::Samplerate->exists(Transformers::$libsDir)) {
33+
throw new RuntimeException('Samplerate library not found. Please run "./vendor/bin/transformers install" to install all dependencies.');
34+
}
35+
}
36+
2837
public static function new($type, bool $owned = true, bool $persistent = false): ?CData
2938
{
3039
return self::ffi()->new($type, $owned, $persistent);

src/FFI/Sndfile.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
declare(strict_types=1);
44

5-
65
namespace Codewithkyrian\Transformers\FFI;
76

87
use Codewithkyrian\Transformers\Transformers;
@@ -18,13 +17,22 @@ class Sndfile
1817
private static function ffi(): FFI
1918
{
2019
if (!isset(self::$ffi)) {
20+
self::validateLibrary();
21+
2122
$headerCode = file_get_contents(Libraries::Sndfile->headerFile(Transformers::$libsDir));
2223
self::$ffi = FFI::cdef($headerCode, Libraries::Sndfile->libFile(Transformers::$libsDir));
2324
}
2425

2526
return self::$ffi;
2627
}
2728

29+
private static function validateLibrary(): void
30+
{
31+
if (!Libraries::Sndfile->exists(Transformers::$libsDir)) {
32+
throw new RuntimeException('Sndfile library not found. Please run "./vendor/bin/transformers install" to install all dependencies.');
33+
}
34+
}
35+
2836
public static function new($type, bool $owned = true, bool $persistent = false): ?CData
2937
{
3038
return self::ffi()->new($type, $owned, $persistent);
@@ -37,9 +45,11 @@ public static function enum(string $name)
3745

3846
/**
3947
* Open the specified file for read, write or both.
48+
*
4049
* @param string $path
4150
* @param int $mode
4251
* @param CData $sfinfo
52+
*
4353
* @return mixed
4454
*/
4555
public static function open(string $path, int $mode, CData $sfinfo): mixed

0 commit comments

Comments
 (0)