@qvac/ocr-ggml 0.27.1 → 0.27.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/fit.d.ts +23 -0
- package/fit.js +31 -0
- package/index.d.ts +2 -0
- package/index.js +7 -20
- package/lib/backends-dir.d.ts +1 -0
- package/lib/backends-dir.js +16 -0
- package/package.json +6 -4
- package/prebuilds/android-arm64/qvac__ocr-ggml.bare +0 -0
- package/prebuilds/darwin-arm64/qvac__ocr-ggml.bare +0 -0
- package/prebuilds/darwin-arm64/qvac__ocr-ggml.bare.exports +14 -13
- package/prebuilds/darwin-x64/qvac__ocr-ggml.bare +0 -0
- package/prebuilds/darwin-x64/qvac__ocr-ggml.bare.exports +111 -56
- package/prebuilds/ios-arm64/qvac__ocr-ggml.bare +0 -0
- package/prebuilds/ios-arm64/qvac__ocr-ggml.bare.exports +15 -14
- package/prebuilds/ios-arm64-simulator/qvac__ocr-ggml.bare +0 -0
- package/prebuilds/ios-arm64-simulator/qvac__ocr-ggml.bare.exports +15 -14
- package/prebuilds/ios-x64-simulator/qvac__ocr-ggml.bare +0 -0
- package/prebuilds/ios-x64-simulator/qvac__ocr-ggml.bare.exports +109 -40
- package/prebuilds/linux-arm64/qvac__ocr-ggml.bare +0 -0
- package/prebuilds/linux-x64/qvac__ocr-ggml.bare +0 -0
- package/prebuilds/win32-x64/qvac__ocr-ggml.bare +0 -0
- package/prebuilds/win32-x64/qvac__ocr-ggml.bare.exports +0 -0
- package/test/integration/fit.test.js +108 -0
- package/test/mobile/integration.auto.cjs +5 -0
- package/test/mobile/test-groups.json +2 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('brittle')
|
|
4
|
+
const path = require('bare-path')
|
|
5
|
+
const { assessFit } = require('../..')
|
|
6
|
+
const { ensureModelPath, ensureDoctrModels, platform } = require('./utils')
|
|
7
|
+
|
|
8
|
+
const gpuBackend = platform === 'darwin' || platform === 'ios' ? 'metal' : 'vulkan'
|
|
9
|
+
|
|
10
|
+
test('assessFit reads both EasyOCR model descriptions without loading an image', async (t) => {
|
|
11
|
+
const pathDetector = path.resolve(await ensureModelPath('detector_craft'))
|
|
12
|
+
const pathRecognizer = path.resolve(await ensureModelPath('recognizer_latin'))
|
|
13
|
+
const fit = assessFit({ pathDetector, pathRecognizer, backendDevice: 'cpu' })
|
|
14
|
+
|
|
15
|
+
t.ok(['fits', 'does-not-fit', 'error'].includes(fit.status))
|
|
16
|
+
t.is(fit.deviceName, 'CPU')
|
|
17
|
+
t.ok(fit.weightsBytes > 0)
|
|
18
|
+
t.is(fit.hostBytes, fit.weightsBytes)
|
|
19
|
+
t.is(fit.deviceBytes, 0)
|
|
20
|
+
for (const key of [
|
|
21
|
+
'weightsBytes',
|
|
22
|
+
'hostBytes',
|
|
23
|
+
'deviceBytes',
|
|
24
|
+
'deviceFreeBytes',
|
|
25
|
+
'deviceTotalBytes'
|
|
26
|
+
]) {
|
|
27
|
+
t.ok(Number.isSafeInteger(fit[key]) && fit[key] >= 0, `${key} is a non-negative safe integer`)
|
|
28
|
+
}
|
|
29
|
+
t.ok(fit.report.includes('excludes image and inference-graph memory'))
|
|
30
|
+
if (fit.status === 'fits') t.is(fit.reason, 'weights-fit')
|
|
31
|
+
else if (fit.status === 'does-not-fit') t.is(fit.reason, 'source-weights-exceed-memory')
|
|
32
|
+
else t.ok(['uncertain', 'device-memory-unavailable'].includes(fit.reason))
|
|
33
|
+
|
|
34
|
+
const reserved = assessFit({
|
|
35
|
+
pathDetector,
|
|
36
|
+
pathRecognizer,
|
|
37
|
+
backendDevice: 'cpu',
|
|
38
|
+
marginBytes: Number.MAX_SAFE_INTEGER
|
|
39
|
+
})
|
|
40
|
+
t.is(reserved.status, 'error', 'an unusably large margin cannot produce a fit verdict')
|
|
41
|
+
t.ok(['uncertain', 'device-memory-unavailable'].includes(reserved.reason))
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('assessFit returns model-unreadable for a missing recognizer', async (t) => {
|
|
45
|
+
const pathDetector = path.resolve(await ensureModelPath('detector_craft'))
|
|
46
|
+
const fit = assessFit({
|
|
47
|
+
pathDetector,
|
|
48
|
+
pathRecognizer: path.join(pathDetector, 'missing-recognizer.gguf')
|
|
49
|
+
})
|
|
50
|
+
t.is(fit.status, 'error')
|
|
51
|
+
t.is(fit.reason, 'model-unreadable')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('assessFit uses the requested gpuDevice when selecting a backend', async (t) => {
|
|
55
|
+
const pathDetector = path.resolve(await ensureModelPath('detector_craft'))
|
|
56
|
+
const pathRecognizer = path.resolve(await ensureModelPath('recognizer_latin'))
|
|
57
|
+
const request = { pathDetector, pathRecognizer, backendDevice: gpuBackend }
|
|
58
|
+
const automatic = assessFit(request)
|
|
59
|
+
const explicit = assessFit({ ...request, gpuDevice: 9999 })
|
|
60
|
+
|
|
61
|
+
t.is(explicit.deviceName, 'CPU', 'out-of-range GPU index falls back to CPU')
|
|
62
|
+
t.is(explicit.deviceBytes, 0)
|
|
63
|
+
if (automatic.deviceName !== 'CPU') {
|
|
64
|
+
t.ok(explicit.deviceName !== automatic.deviceName, 'explicit GPU index changes placement')
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('assessFit recognizes actual DocTR detector and CPU-assist placement', async (t) => {
|
|
69
|
+
const models = await ensureDoctrModels()
|
|
70
|
+
if (!models) {
|
|
71
|
+
t.pass('DocTR models are unavailable on this device')
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
const pathDetector = path.resolve(models.db_mobilenet_v3_large)
|
|
75
|
+
const pathRecognizer = path.resolve(models.crnn_mobilenet_v3_small)
|
|
76
|
+
const request = {
|
|
77
|
+
pathDetector,
|
|
78
|
+
pathRecognizer,
|
|
79
|
+
pipelineType: 'doctr',
|
|
80
|
+
backendDevice: gpuBackend,
|
|
81
|
+
detectionBackendDevice: gpuBackend,
|
|
82
|
+
recognizerCpuAssist: false
|
|
83
|
+
}
|
|
84
|
+
const singleDevice = assessFit(request)
|
|
85
|
+
t.ok(singleDevice.weightsBytes > 0, 'DocTR model metadata was read')
|
|
86
|
+
t.ok(singleDevice.deviceName, 'DocTR backend was selected')
|
|
87
|
+
t.ok(
|
|
88
|
+
singleDevice.reason !== 'unsupported-config',
|
|
89
|
+
'matching detector and recognizer devices are supported'
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
if (singleDevice.deviceName === 'CPU') {
|
|
93
|
+
t.pass('GPU unavailable; split-device checks require a GPU')
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const assisted = assessFit({ ...request, recognizerCpuAssist: true })
|
|
98
|
+
t.is(assisted.status, 'error')
|
|
99
|
+
t.is(assisted.reason, 'unsupported-config', 'GPU recognition with CPU assist is split')
|
|
100
|
+
|
|
101
|
+
const splitDetector = assessFit({
|
|
102
|
+
...request,
|
|
103
|
+
backendDevice: 'cpu',
|
|
104
|
+
detectionBackendDevice: gpuBackend
|
|
105
|
+
})
|
|
106
|
+
t.is(splitDetector.status, 'error')
|
|
107
|
+
t.is(splitDetector.reason, 'unsupported-config', 'CPU recognition with GPU detection is split')
|
|
108
|
+
})
|
|
@@ -101,6 +101,11 @@ async function runErrorHandlingTest (options = {}) { // eslint-disable-line no-u
|
|
|
101
101
|
return runIntegrationModule('../integration/error-handling.test.js', options)
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
async function runFitTest (options = {}) { // eslint-disable-line no-unused-vars -- called dynamically by the mobile test runner via string lookup
|
|
105
|
+
if (typeof __shouldRunTest === 'function' && !__shouldRunTest('runFitTest')) return __FILTERED
|
|
106
|
+
return runIntegrationModule('../integration/fit.test.js', options)
|
|
107
|
+
}
|
|
108
|
+
|
|
104
109
|
async function runFullCoverageTest (options = {}) { // eslint-disable-line no-unused-vars -- called dynamically by the mobile test runner via string lookup
|
|
105
110
|
if (typeof __shouldRunTest === 'function' && !__shouldRunTest('runFullCoverageTest')) return __FILTERED
|
|
106
111
|
return runIntegrationModule('../integration/full-coverage.test.js', options)
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"runDoctrModelsTest",
|
|
13
13
|
"runDoctrParamValidationTest",
|
|
14
14
|
"runErrorHandlingTest",
|
|
15
|
+
"runFitTest",
|
|
15
16
|
"runFullCoverageTest",
|
|
16
17
|
"runFullOcrSuiteTest"
|
|
17
18
|
],
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
"runDoctrModelsTest",
|
|
49
50
|
"runDoctrParamValidationTest",
|
|
50
51
|
"runErrorHandlingTest",
|
|
52
|
+
"runFitTest",
|
|
51
53
|
"runFullCoverageTest",
|
|
52
54
|
"runFullOcrSuiteTest"
|
|
53
55
|
],
|