From 7e3fedb7863ef18ccac3d1660516a11c99ee550b Mon Sep 17 00:00:00 2001 From: eric8810 Date: Tue, 6 Oct 2026 23:43:58 +0800 Subject: [PATCH] =?UTF-8?q?fix(npu):=20=E5=8F=8C=E8=8A=AF=E5=8F=A6?= =?UTF-8?q?=E8=BD=BD=EF=BC=8C=E8=BD=BB=E5=8D=B7=E5=A6=82=E5=88=9D=20=C2=B7?= =?UTF-8?q?=20separate=20optional=20NPU=20support=20packages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/npm-release.yml | 45 +-------- .github/workflows/npu-support-release.yml | 106 ++++++++++++++++++++++ CHANGELOG.md | 17 ++-- README.md | 2 + README.zh-CN.md | 2 + docs/amd-npu-acceleration.md | 4 +- docs/implementation-status.md | 2 +- docs/intel-npu-acceleration.md | 2 + docs/npu-runtime-release.md | 33 +++++-- docs/releases/npm-0.5.9.en.md | 40 +++++--- docs/releases/npm-0.5.9.md | 46 ++++++---- package-lock.json | 12 +++ packages/light-ocr/README.md | 11 +++ packages/runtime/README.md | 14 ++- packages/runtime/package.json | 12 +++ packages/runtime/src/index.cjs | 7 +- packages/runtime/src/load-native.cjs | 26 +++++- tools/npm_release.py | 12 +++ tools/npu/package_support.py | 51 +++++++++++ 19 files changed, 339 insertions(+), 105 deletions(-) create mode 100644 .github/workflows/npu-support-release.yml create mode 100644 tools/npu/package_support.py diff --git a/.github/workflows/npm-release.yml b/.github/workflows/npm-release.yml index 72160e2..d5310c6 100644 --- a/.github/workflows/npm-release.yml +++ b/.github/workflows/npm-release.yml @@ -13,11 +13,6 @@ on: required: true default: false type: boolean - npu_sdk_run_id: - description: Optional override containing both locked Intel and AMD deployment SDKs - required: false - default: "" - type: string permissions: contents: read @@ -47,10 +42,6 @@ jobs: python tools/npm_release.py ensure-unpublished --version "$RELEASE_VERSION" build-native: - # The locked AMD asset is attached to a draft until release publication. - permissions: - contents: write - actions: read needs: validate name: build ${{ matrix.id }} strategy: @@ -93,30 +84,6 @@ jobs: - name: Bootstrap pinned native dependencies shell: bash run: python tools/bootstrap_dependencies.py --cache-dir .cache/dependencies - - name: Download distributable NPU SDKs - if: matrix.id == 'linux-x64' && inputs.npu_sdk_run_id != '' - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: npu-release-sdks - path: dist/npu-sdk - run-id: ${{ inputs.npu_sdk_run_id }} - github-token: ${{ github.token }} - - name: Prepare packaged Intel and opt-in AMD NPU payloads - if: matrix.id == 'linux-x64' - shell: bash - env: - GH_TOKEN: ${{ github.token }} - run: | - if [[ ! -d dist/npu-sdk/openvino ]]; then - python tools/npu/build_openvino.py \ - --package-cache .cache/npu-packages --output-dir dist/npu-sdk/openvino - fi - if [[ ! -d dist/npu-sdk/amdnpu ]]; then - python tools/npu/fetch_amdnpu.py \ - --package-cache .cache/npu-packages --output-dir dist/npu-sdk/amdnpu - fi - python tools/npu/prepare_release.py --sdk-root dist/npu-sdk --github-env "$GITHUB_ENV" \ - --require-provider openvino --require-provider amdnpu - name: Fetch the pinned PDF renderer for npm bundling (Unix) if: runner.os != 'Windows' shell: bash @@ -179,8 +146,6 @@ jobs: -DLIGHT_OCR_DEPENDENCY_CACHE_DIR="$PWD/.cache/dependencies" -DLIGHT_OCR_ONNXRUNTIME_FLAVOR=${{ matrix.runtime_flavor }} -DLIGHT_OCR_WEBGPU_SDK_DIR="$PWD/dist/webgpu-sdk/${{ matrix.id }}" - -DLIGHT_OCR_OPENVINO_SDK_DIR="$OPENVINO_SDK_DIR" - -DLIGHT_OCR_AMDNPU_SDK_DIR="$AMDNPU_SDK_DIR" -DLIGHT_OCR_BUILD_NODE=ON -DLIGHT_OCR_BUILD_TESTS=OFF -DLIGHT_OCR_BUILD_TOOLS=OFF @@ -213,13 +178,6 @@ jobs: - name: Stage native package input shell: bash run: | - npu_arguments=() - if [[ -n "${OPENVINO_SDK_DIR:-}" ]]; then - npu_arguments+=(--openvino-sdk-dir "$OPENVINO_SDK_DIR") - fi - if [[ -n "${AMDNPU_SDK_DIR:-}" ]]; then - npu_arguments+=(--amdnpu-sdk-dir "$AMDNPU_SDK_DIR") - fi python tools/npm_release.py stage-native \ --platform-id "${{ matrix.id }}" \ --build-dir build-npm \ @@ -228,8 +186,7 @@ jobs: --pdfium-dir .cache/pdfium-package/node_modules/pdfium-native \ --output-dir "dist/native-input/${{ matrix.id }}" \ --runtime-flavor "${{ matrix.runtime_flavor }}" \ - --webgpu-artifact-manifest "dist/webgpu-sdk/${{ matrix.id }}/artifact-manifest.json" \ - "${npu_arguments[@]}" + --webgpu-artifact-manifest "dist/webgpu-sdk/${{ matrix.id }}/artifact-manifest.json" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with: name: native-${{ matrix.id }} diff --git a/.github/workflows/npu-support-release.yml b/.github/workflows/npu-support-release.yml new file mode 100644 index 0000000..e572179 --- /dev/null +++ b/.github/workflows/npu-support-release.yml @@ -0,0 +1,106 @@ +name: NPU support packages + +on: + workflow_dispatch: + inputs: + version: + description: Patch version of the matching light-ocr release + default: '0.5.9' + required: true + type: string + publish_to_registry: + description: Publish both independent support packages under next + default: false + required: true + type: boolean + +permissions: + contents: read + +jobs: + build: + # The AMD deployment archive remains a draft asset until v0.5.9 ships. + permissions: + contents: write + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + provider: [openvino, amdnpu] + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '22' + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 + with: + python-version: '3.11' + - name: Prepare the selected provider only + env: + GH_TOKEN: ${{ github.token }} + PROVIDER: ${{ matrix.provider }} + RELEASE_VERSION: ${{ inputs.version }} + run: | + test "$RELEASE_VERSION" = "$(cat VERSION)" + python tools/bootstrap_dependencies.py --cache-dir .cache/dependencies + if [[ "$PROVIDER" == openvino ]]; then + python tools/npu/build_openvino.py --package-cache .cache/npu --output-dir dist/sdk + else + python tools/npu/fetch_amdnpu.py --package-cache .cache/npu --output-dir dist/sdk + fi + - name: Build a separate CPU and NPU addon + env: + PROVIDER: ${{ matrix.provider }} + run: | + node_version="$(node -p process.versions.node)" + npx --yes node-gyp@11.4.2 install "$node_version" --devdir "$PWD/.cache/node-gyp" + sdk_option="LIGHT_OCR_${PROVIDER^^}_SDK_DIR" + cmake -S . -B build-support -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DLIGHT_OCR_DEPENDENCY_CACHE_DIR="$PWD/.cache/dependencies" \ + "-D$sdk_option=$PWD/dist/sdk" \ + -DLIGHT_OCR_BUILD_NODE=ON -DLIGHT_OCR_BUILD_TESTS=OFF -DLIGHT_OCR_BUILD_TOOLS=OFF \ + -DLIGHT_OCR_NODE_INCLUDE_DIR="$PWD/.cache/node-gyp/$node_version/include/node" + cmake --build build-support --parallel 2 + - name: Package the independent support addon + env: + PROVIDER: ${{ matrix.provider }} + run: | + python tools/generate_release_metadata.py --build-dir build-support \ + --output-dir reports/support --platform-id linux-x64 --model-free + python tools/npu/package_support.py --provider "$PROVIDER" \ + --build-dir build-support --metadata-dir reports/support \ + --sdk-dir dist/sdk --output-dir dist/package + mkdir -p dist/tarballs + npm pack ./dist/package --ignore-scripts --json --pack-destination dist/tarballs > dist/tarballs/pack-manifest.json + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + with: + name: npu-support-${{ matrix.provider }}-${{ inputs.version }} + path: dist/tarballs/ + retention-days: 90 + if-no-files-found: error + + publish: + needs: build + if: inputs.publish_to_registry + runs-on: ubuntu-24.04 + environment: npm-release + permissions: + contents: read + id-token: write + steps: + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '22' + registry-url: https://registry.npmjs.org + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 + with: + pattern: npu-support-*-${{ inputs.version }} + path: dist/support + - name: Publish the explicitly installed support packages + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + for archive in dist/support/*/*.tgz; do + npm publish "$archive" --tag next --access public --provenance + done diff --git a/CHANGELOG.md b/CHANGELOG.md index 398b4c6..c75738a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,26 +10,27 @@ Release preparation; npm publication and GitHub Release are pending. ### Added -- Added a bundled Intel NPU backend (`provider: "openvino"`) for Linux x64. +- Added a separately installed Intel NPU backend (`provider: "openvino"`) for Linux x64. Builds configured with `LIGHT_OCR_OPENVINO_SDK_DIR` load the OpenVINO C runtime at run time, run detection and 20-bucket recognition on the NPU, and - place `openvino` first in the package Auto policy - (`openvino → webgpu → cpu`); hosts without an NPU skip it with + support explicit OpenVINO selection; default packages retain their existing + Auto policy; explicit requests on hosts without an NPU fail with `adapter_unavailable`. Added a pinned native SDK extractor, package-local runtime descriptor 2.1, numeric driver/compiler checks, and reviewed-evidence - release staging with optional device reports. The 0.5.9 Linux x64 build includes - pinned OpenVINO 2026.4.0 libraries. See + release staging with optional device reports. The optional OpenVINO support package includes + pinned OpenVINO 2026.4.0 libraries; default platform packages do not. See [Intel NPU 加速技术方案](docs/intel-npu-acceleration.md). -- Added a bundled AMD NPU backend (`provider: "amdnpu"`) for Linux x64 +- Added a separately installed AMD NPU backend (`provider: "amdnpu"`) for Linux x64 glibc and Ryzen AI STX/KRK devices. It isolates the vendor ORT runtime, loads 20 immutable BF16 recognition contexts, and runs detection on CPU. Added model compilation and SDK import tools, descriptor validation, license/SBOM staging, and candidate/release workflows. AMD is excluded from Auto and enabled only through `execution.provider: "amdnpu"` (or `--provider amdnpu`). NPU device reports are optional for release; - `deviceValidated` remains false. The 0.5.9 Linux x64 build includes Ryzen AI 1.8 + `deviceValidated` remains false. The optional AMD support package includes Ryzen AI 1.8 deployment libraries and real compiled contexts bound to Small 0.3.4. - Other platforms retain their existing providers. See [AMD NPU 加速技术方案](docs/amd-npu-acceleration.md) + Neither support package is automatically installed or selected by Auto. + The existing Small model bundle remains unchanged. See [AMD NPU 加速技术方案](docs/amd-npu-acceleration.md) and [NPU SDK 构建与发布](docs/npu-runtime-release.md). ## [0.5.8] - 2026-09-24 diff --git a/README.md b/README.md index e17cfd9..2d401f0 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,8 @@ error model, while each install contains only its selected model. | Tiny | `@arcships/light-ocr-tiny@next` / `light-ocr-tiny` | ~6.3 MB | preview; 49 languages, no Japanese | | Medium | `@arcships/light-ocr-medium@next` / `light-ocr-medium` | ~139 MB | preview; quality-first | +NPU support is installed separately through `@arcships/light-ocr-openvino-linux-x64-gnu` or `@arcships/light-ocr-amdnpu-linux-x64-gnu` and requires explicit provider selection. The default install contains neither provider's libraries nor compiled models; the existing Small model bundle stays unchanged. See the [NPU installation guide](docs/npu-runtime-release.md#用户安装与显式开启). + Tiny and Medium stay on `next`; they do not change what `npm install @arcships/light-ocr` installs. diff --git a/README.zh-CN.md b/README.zh-CN.md index 3585f2b..8351feb 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -181,6 +181,8 @@ Small 继续作为稳定默认。Tiny 和 Medium 是 `next` tag 下的可选 pre | Tiny | `@arcships/light-ocr-tiny@next` / `light-ocr-tiny` | 约 6.3 MB | Preview;49 种语言,不含日语 | | Medium | `@arcships/light-ocr-medium@next` / `light-ocr-medium` | 约 139 MB | Preview;精度优先 | +NPU 支持通过单独安装的 `@arcships/light-ocr-openvino-linux-x64-gnu` / `@arcships/light-ocr-amdnpu-linux-x64-gnu` 提供,均需显式配置 provider。普通安装不含它们的运行库或编译模型,Small 模型制品保持不变。见 [NPU 安装说明](docs/npu-runtime-release.md#用户安装与显式开启)。 + Tiny/Medium 保持在 `next`;它们不会改变 `npm install @arcships/light-ocr` 的安装内容。 diff --git a/docs/amd-npu-acceleration.md b/docs/amd-npu-acceleration.md index b78b34c..37804f2 100644 --- a/docs/amd-npu-acceleration.md +++ b/docs/amd-npu-acceleration.md @@ -1,6 +1,6 @@ # AMD NPU 加速技术方案 -更新时间:2026-10-06。状态:Linux x64 glibc 后端与打包改造已实现,默认关闭、配置显式开启;0.5.9 发布输入已包含 Ryzen AI 1.8 的原生部署库与 Small 0.3.4 的 20 个真实 BF16 context。无需真机即可完成编译,尚未执行 AMD 设备推理。正式 npm 发布仍待完成。 +更新时间:2026-10-06。状态:Linux x64 glibc 后端与打包改造已实现,默认关闭、配置显式开启;0.5.9 独立支持包的构建输入已包含 Ryzen AI 1.8 的原生部署库与 Small 0.3.4 的 20 个真实 BF16 context。无需真机即可完成编译,尚未执行 AMD 设备推理。正式 npm 发布仍待完成。 ## 范围与模型路线 @@ -22,7 +22,7 @@ BF16 路线由 VAIML 编译 FP32 ONNX,生成可嵌入权重与微码的 EPCont ## 默认关闭与发布策略 -AMD 始终排除在 Auto 候选列表之外;用户通过 `execution.provider: "amdnpu"`、CLI `--provider amdnpu` 或 C++ 的 `ExecutionProvider::amdnpu` 显式开启。0.5.9 Linux x64 发布构建默认附带 vendor SDK 与匹配的 Small 识别模型;运行时未配置 AMD 时不装载 vendor ORT。 +AMD 始终排除在 Auto 候选列表之外;用户通过 `execution.provider: "amdnpu"`、CLI `--provider amdnpu` 或 C++ 的 `ExecutionProvider::amdnpu` 显式开启。0.5.9 独立 AMD 支持包附带 vendor SDK 与匹配的 Small 识别模型,普通平台包不包含它们;运行时未配置 AMD 时不装载 vendor ORT。 按维护者决定,NPU 真机验收不再阻塞发布。SDK 导入的 `qualificationOnly: true` 仅记录尚无设备证据,平台包可随其他已满足条件的运行时一起发布;`deviceValidated` 保持 `false`。库存、模型哈希、依赖闭包和许可证校验继续执行,设备报告可选。 diff --git a/docs/implementation-status.md b/docs/implementation-status.md index 25bc695..ea7b9df 100644 --- a/docs/implementation-status.md +++ b/docs/implementation-status.md @@ -92,7 +92,7 @@ ## 0.5.9 NPU 发布准备(2026-10-06) -Linux x64 glibc 双 NPU Core/Node 构建与 npm native staging 已完成。默认发布输入包含 OpenVINO 2026.4.0,以及 Ryzen AI 1.8 的 20 个原生部署库和绑定 Small 0.3.4 的 20 个真实 BF16 context。Intel 进入 Auto;AMD 始终默认关闭,由配置显式开启。未执行 AMD 设备推理,`deviceValidated` 保持 false;真机验收不作为发布前置。版本、归档哈希与后续发布步骤见 [0.5.9 发布记录](releases/npm-0.5.9.md)。 +Linux x64 glibc 双 NPU 实现与实际 AMD 模型编译已完成。旧 0.5.9 候选把两套 NPU 混入基础包,已明确废弃。拆包修正将 OpenVINO/AMD 放入单独安装的支持包,普通包保留既有模型制品与 Apple/WebGPU/CPU 路线。两套 NPU 均需安装后显式配置;不做真机验收,`deviceValidated` 保持 false。见 [0.5.9 发布记录](releases/npm-0.5.9.md)。 ## 本机最终验证快照 diff --git a/docs/intel-npu-acceleration.md b/docs/intel-npu-acceleration.md index 69b4b3f..7b7f51c 100644 --- a/docs/intel-npu-acceleration.md +++ b/docs/intel-npu-acceleration.md @@ -1,5 +1,7 @@ # Intel NPU 加速技术方案 +> 2026-10-06 发布修正:npm 默认包不携带 OpenVINO。用户单独安装 `@arcships/light-ocr-openvino-linux-x64-gnu`,显式指定 `provider: "openvino"`。默认 npm Auto 保持原有路线;下文的自定义源码构建/历史 Auto 方案不代表普通安装会下载或选用 NPU。见 [独立支持包说明](npu-runtime-release.md)。 + 状态:Phase B 后端和 Phase D 打包代码已实现;Linux x64 真机 14-fixture 已有验证记录;按维护者决定,真机 Gate 不再作为发布前置;当前 npm 包未包含 OpenVINO。构建和发布说明见 [NPU SDK 构建与发布](npu-runtime-release.md)。 更新时间:2026-09-29 diff --git a/docs/npu-runtime-release.md b/docs/npu-runtime-release.md index 01fc162..1d87911 100644 --- a/docs/npu-runtime-release.md +++ b/docs/npu-runtime-release.md @@ -1,6 +1,6 @@ # NPU SDK 构建与发布 -当前实现覆盖 Linux x64 glibc。Intel 使用 OpenVINO C API;AMD 使用独立装载的 Ryzen AI ORT 与预编译 BF16 识别模型。安装后的 OCR 进程无需 Python,系统仍需厂商 NPU 驱动,AMD 路线使用 Ryzen AI 1.8 支持的 Ubuntu 24.04/glibc 环境。0.5.9 的 Linux x64 发布构建默认附带两套运行时,AMD 默认关闭。 +当前实现覆盖 Linux x64 glibc。Intel 使用 OpenVINO C API;AMD 使用独立装载的 Ryzen AI ORT 与预编译 BF16 识别模型。安装后的 OCR 进程无需 Python,系统仍需厂商 NPU 驱动,AMD 路线使用 Ryzen AI 1.8 支持的 Ubuntu 24.04/glibc 环境。0.5.9 将两套 NPU 分别放入用户单独安装的支持包;普通平台包不包含这些库和 context,默认模型制品不变。 ## Intel 候选 SDK @@ -67,19 +67,24 @@ cmake --build build-npu --parallel 2 AMD 默认需要 CPU detector,且其模型绑定具体识别模型哈希;换用其他 tier 时需重新编译对应 SDK。Windows、arm64 和 musl 不接受当前 NPU SDK。 -## 用户显式开启 AMD +## 用户安装与显式开启 -含 AMD SDK 与模型的构建默认不会选择或装载 AMD runtime。Node.js 用户在创建引擎时指定: +```bash +npm install @arcships/light-ocr +# 按设备单独选择一个支持包 +npm install @arcships/light-ocr-amdnpu-linux-x64-gnu@0.5.9 +# 或 npm install @arcships/light-ocr-openvino-linux-x64-gnu@0.5.9 +``` ```js const engine = await createEngine({ - execution: { provider: "amdnpu" } + execution: { provider: "amdnpu" } // Intel 使用 "openvino" }); ``` -模型无关的 `@arcships/light-ocr-runtime` 还需传入 `bundlePath`;模型 facade 自动提供 bundle。CLI 使用 `--provider amdnpu`;C++ 使用 `options.execution.provider = ExecutionProvider::amdnpu`。省略该配置或指定 `auto` 会走默认候选列表。显式 AMD 请求不静默回退;缺少包内 AMD SDK/模型、设备或驱动时报告对应错误。 +模型无关 runtime 还需 `bundlePath`。两套支持包都是 optional peer,不随普通安装自动下载;显式 provider 才选择对应独立 addon,Auto 保持基础包策略。缺少包时报告 `unsupported_capability`,没有静默回退。AMD 的 20 个 context 绑定 Small 0.3.4。 -发布不要求 NPU 真机报告;`deviceValidated` 保持 `false`。SDK 和真实编译模型通过锁定的部署包自动随构建交付。 +支持包内包含原生依赖和产物身份;终端用户无需完整 SDK/Python,仍需系统 NPU 驱动。真机报告不作为发布前置,`deviceValidated` 保持 false。 ## 可选设备报告 @@ -119,10 +124,18 @@ python tools/npu/accept_qualification.py \ ## CI 与 npm staging -`NPU native candidates` workflow 默认取得 Intel 与 AMD SDK 并生成双 NPU Node 候选构建。可输入另一个 run 的 `amdnpu-candidate-sdk` artifact,内容应为 AMD SDK 目录。始终上传可分发的 `npu-release-sdks`,无需设备报告。可选的 `npu-reviewed-reports` artifact 按 `openvino/*.json`、`amdnpu/*.json` 放置;仅在主动提供报告时才检查其绑定关系。 +`npm release` 只生成普通八平台闭包,完全移除两套 NPU SDK 输入。`assemble` 拒绝含 NPU provider/目录的默认平台输入,防止旧的大包再次发布。 + +`NPU support packages` workflow 分别构建 CPU+OpenVINO、CPU+AMD addon,通过 `tools/npu/package_support.py` 生成两个独立 npm 包,再分别上传其 tarball 与 pack manifest。两个包不依赖模型包,也不进入基础包的 dependencies/optionalDependencies;runtime 仅声明 optional peer。发布输入默认关闭。 -从 0.5.9 发布准备起,`npm release` 默认为 Linux x64 准备锁定的 Intel 与 AMD SDK,缺少任一套均阻止发布构建。可选 `npu_sdk_run_id` 读取同仓库的 `npu-release-sdks`(根目录下为 `openvino/`、`amdnpu/`),仅 Linux x64 构建使用。CI 在配置 CMake 前验证 SDK 库存、模型、配置和哈希;已附带的接受报告仍会校验,但不要求提供报告。 +本地单独打包示例: -本地 `tools/npm_release.py stage-native` 接受 `--openvino-sdk-dir` 和 `--amdnpu-sdk-dir`;SDK 需与构建 addon 使用的版本、资格 ID 和包含的 provider 一致。NPU SDK 的 `qualificationOnly` 记录其设备证据状态,不再使整个平台包变成 qualification build;无需真机报告即可 staging。WebGPU 自身的既有资格门槛仍适用,正式 `assemble` 仍拒绝基础运行时的 qualification build。许可证、SBOM、SDK manifest 和可选报告随平台包保存。 +```bash +python tools/generate_release_metadata.py --build-dir build-support \ + --output-dir reports/support --platform-id linux-x64 --model-free +python tools/npu/package_support.py --provider amdnpu --build-dir build-support \ + --metadata-dir reports/support --sdk-dir dist/npu-sdk/amdnpu --output-dir dist/support-package +npm pack ./dist/support-package --ignore-scripts +``` -正式发布仍沿用项目补丁版本策略;当前候选尚未发布到 npm。 +每个 support addon 必须只编译所选 SDK,保证 descriptor 与原生 policy 一致;版本必须匹配 Core。SDK 库存、模型、哈希、许可证与 SBOM 均保留,设备报告仍可选。WebGPU 基础运行时的既有发布规则不变。 diff --git a/docs/releases/npm-0.5.9.en.md b/docs/releases/npm-0.5.9.en.md index 73226e8..9fc08f2 100644 --- a/docs/releases/npm-0.5.9.en.md +++ b/docs/releases/npm-0.5.9.en.md @@ -20,22 +20,38 @@ NPU implementation: [PR #67](https://github.com/arcships/light-ocr/pull/67), mer ## Changes -- Linux x64 glibc release builds include pinned OpenVINO 2026.4.0 by default. Auto tries Intel NPU before WebGPU and CPU, running detection and 20-bucket recognition when supported. Creation-time device/model/driver exclusions advance to the next provider. -- Linux x64 glibc builds include Ryzen AI 1.8 native deployment libraries and 20 real BF16 recognition contexts bound to Small 0.3.4. AMD stays outside Auto; explicitly select `execution: { provider: "amdnpu" }` or `--provider amdnpu`. Detection uses CPU; STX/KRK devices are the target. Tiny/Medium require separately compiled contexts. -- The workflow fetches the immutable AMD deployment archive automatically. End users need vendor drivers, without installing the full SDK or Python. -- Hardware qualification reports are optional for NPU shipping. Unvalidated devices remain `deviceValidated: false`; inventory, hashes, model binding, licenses and existing base-runtime checks remain enforced. -- NPU packages use runtime descriptor 2.1; other packages retain 2.0. Windows, arm64 and musl retain their existing provider routes. Model versions, the `>=22.0.0` Node floor and public API contracts are unchanged. +- The default Small package retains its existing approximately 39 MB model promise and immutable model package 0.3.4. No AMD/OpenVINO libraries or compiled NPU contexts enter the default dependency closure. +- Eight base native packages retain Apple/WebGPU/CPU policies. NPU support is separately installed as `@arcships/light-ocr-openvino-linux-x64-gnu@0.5.9` or `@arcships/light-ocr-amdnpu-linux-x64-gnu@0.5.9`. +- These are optional peers, without automatic installation. Explicit `execution.provider` selects the matching separate addon; Auto does not select either NPU. Vendor drivers are required; device inference remains unqualified. +- AMD includes 20 actual BF16 contexts bound to Small 0.3.4 and is substantially larger. Other tiers need their own compiled contexts. ## Release sequence -1. Merge preparation and select main with Core `0.5.9`. -2. Run `npm release` with `version=0.5.9` and `publish_to_registry=false`. Both SDKs are prepared automatically on Linux x64. An optional `npu_sdk_run_id` overrides both SDKs and must contain `openvino/` and `amdnpu/`. Draft asset downloads use the workflow GitHub token. AMD stays opt-in. -3. Review eight-platform builds, offline image/PDF smoke and the tarball manifest. Record the source SHA, run ID, 13 new package identities and artifact hashes. -4. Publish to `next` with `publish_to_registry=true` and record registry reinstall results. -5. Run `npm promote` with the publication run ID and `tag=latest`; promote only Small/runtime/native. Document and preview facades stay on `next`. -6. Update the draft release target to the final source commit, attach the manifest/artifact links, and fill publication dates and both release records before publishing `v0.5.9`. +1. Merge the split-package correction into main. +2. Run `npm release` with version 0.5.9 and publication disabled for the ordinary eight-platform closure. +3. Run `NPU support packages` separately, also with publication disabled, to build the two independent NPU packages. +4. Record final source commits, both runs, exact package sizes and hashes. Base assembly rejects NPU providers and directories. +5. Publish the base closure through its existing next/latest sequence; publish independent support packages through their own workflow under next. Document and previews remain on next. +6. Update the draft target, publication identities and dates before publishing v0.5.9. -Preparation does not publish npm packages, promote tags or publish the GitHub draft. PR #67 CI is implementation evidence, not the eight-platform 0.5.9 release result. All 13 new package identities are vacant (the complete manifest also reuses two preview model packages). Intel+AMD Core/Node were reconfigured and built with version 0.5.9; version closure, lockfile and script syntax checks passed. No new local tests were run; artifact integrity and publication runs remain pending. All 20 AMD recognition contexts were actually compiled; 20 native libraries and 56 inventory files were imported. No AMD inference or NPU hardware qualification was performed. +## Evidence and rejected candidate + +The previous candidate run `37480252872` passed eight-platform build/smoke, but incorrectly bundled both NPUs into Linux x64: 577,384,672 compressed bytes and 1,455,176,275 unpacked bytes. **Do not publish this candidate; rebuild from corrected main.** + +Source NPU build run `37469626258` succeeded. All 20 AMD contexts were actually compiled without device inference. Original SDK provenance and deployment archive identity remain locked in `amdnpu-source.lock.json` and `amdnpu.lock.json`; the approximately 508 MiB archive supplies only the independently installed AMD support package. + +The 13 new base identities were vacant. Final corrected tarball identities and both support-package builds are recorded after generation. + +## Local split-package build evidence + +All three addons (base CPU, independent OpenVINO and independent AMD) built and staged separately. Base inventory contains CPU only, no NPU directories, with 33,091,890 native bytes; this local baseline excludes the production WebGPU/PDF attachments. Both independent support tarballs were generated: + +| Package | Compressed bytes | Unpacked bytes | +| --- | ---: | ---: | +| `@arcships/light-ocr-amdnpu-linux-x64-gnu` | 548,609,874 | 1,390,267,314 | +| `@arcships/light-ocr-openvino-linux-x64-gnu` | 26,363,501 | 72,478,453 | + +These are local packaging artifacts, not the corrected eight-platform release run. No new local tests or device inference were performed. ## Rollback diff --git a/docs/releases/npm-0.5.9.md b/docs/releases/npm-0.5.9.md index 83a5964..52f0391 100644 --- a/docs/releases/npm-0.5.9.md +++ b/docs/releases/npm-0.5.9.md @@ -23,31 +23,39 @@ ## 用户可见变化 -- Linux x64 glibc 平台包默认附带锁定的 OpenVINO 2026.4.0 原生运行时;Intel NPU 在 Auto 中位于 WebGPU/CPU 前。有可用 NPU 时运行检测和 20 桶识别;无设备、模型不支持或驱动过旧时按创建阶段策略继续选择后续 provider。 -- Linux x64 glibc 发布构建默认附带 Ryzen AI 1.8 原生部署库及 Small 0.3.4 的 20 个真实 BF16 识别 context。AMD 始终默认关闭,不进入 Auto;通过 `execution: { provider: "amdnpu" }` 或 `--provider amdnpu` 显式开启。检测使用 CPU,目标为 STX/KRK;Tiny/Medium 需另行编译,不能复用 Small context。 -- 发布工作流自动下载哈希锁定的 AMD 部署归档,不需要维护者另行提供 SDK。终端用户仍需系统厂商驱动,无需 SDK/Python 安装。 -- NPU 真机验收不作为发布前置;未验证的 NPU 会话保持 `deviceValidated: false`。库存、哈希、模型绑定、许可证和基础运行时的既有发布检查保留。 -- 包内 NPU 描述采用 schema 2.1;不含 NPU 的平台保持 2.0。新增模型配置、版本与产物信息,Node loader 在装载前完成验证。 -- 其他平台继续使用现有 Apple/WebGPU/CPU 路线;Windows、arm64 和 musl 没有本次 NPU 后端。模型包版本、Node 安装下限 `>=22.0.0` 及 public API 保持既有契约。 +- 主包保持原来的约 39 MB Small 模型承诺:模型包 `0.3.4` 及其锁定制品不变,不加入 AMD/OpenVINO 运行库或 AMD 编译模型。 +- 默认 runtime 的八个平台依赖均保持基础运行时,Auto 沿用 Apple/WebGPU/CPU 路线。 +- 两套 NPU 独立分发:`@arcships/light-ocr-openvino-linux-x64-gnu@0.5.9`、`@arcships/light-ocr-amdnpu-linux-x64-gnu@0.5.9`。用户单独安装后,配置 `execution.provider` 为 `openvino` 或 `amdnpu`。optional peer 不会自动安装;安装后也不进入默认 Auto。 +- 支持包各自包含匹配的 addon、原生依赖、哈希、许可证与 SBOM;AMD 包另外含 Small 0.3.4 的 20 个真实 BF16 context,体积较大。系统仍需厂商驱动,无需终端用户安装完整 SDK/Python。 +- 不要求 NPU 真机验收,`deviceValidated: false`;Windows、arm64、musl 不含这两套支持包。 ## Release 操作 -1. 合并版本准备 PR,确认 main 中 Core 为 `0.5.9`。 -2. 运行 `npm release` workflow,输入 `version=0.5.9`、`publish_to_registry=false`。Linux x64 默认从锁文件取得 Intel 与 AMD SDK,无需填写 NPU run ID。 -3. 可选 `npu_sdk_run_id` 仅用于覆盖默认 SDK 输入;须同时包含 `openvino/` 与 `amdnpu/`。草稿附件下载使用 workflow 的 GitHub token;保持 Release 草稿及附件可用。 -4. 审阅八平台构建、离线安装/图片/PDF smoke 与 tarball manifest;将运行 ID、精确来源提交、13 个新 package identity 和制品哈希补录本文件。 -5. 用 `publish_to_registry=true` 发布到 `next`,记录发布 run,并确认 registry 回装结果。 -6. 运行 `npm promote`:`version=0.5.9`、`release_run_id=<正式发布run>`、`tag=latest`。仅晋升 stable Small/runtime/native;Document 与 Tiny/Medium 保留 `next`。 -7. 将 GitHub Release 草稿 target 更新为正式 main 来源提交,附上 release-manifest 和公开制品链接;确认发布结果后更新 Changelog 日期、两份发布记录和 Release 状态,再发布 `v0.5.9`。 +1. 合并拆包修正,确认 main 中 Core 为 `0.5.9`。 +2. 运行 `npm release`,输入 `version=0.5.9`、`publish_to_registry=false`,生成普通八平台候选包。基础打包禁止 NPU provider 或目录混入。 +3. 独立运行 `NPU support packages`(`npu-support-release.yml`),输入 `version=0.5.9`、`publish_to_registry=false`,生成两套单独安装的支持包。 +4. 记录最终 main 来源提交、两个构建 run、npm tarball 的精确大小/SHA-256;审阅基础安装闭包,不把支持包归档总量视为主包大小。 +5. 按既有正式流程发布基础包到 `next`,完成 registry 回装后晋升 stable Small/runtime/native。独立支持包通过其自身 workflow 发布到 `next`,Document/preview 继续保留 `next`。 +6. 将草稿 target 指向最终 main 提交,补录实际发布身份、日期和正式制品链接,再公开 `v0.5.9`。 -准备阶段不会主动调用 registry publish、晋升 dist-tag 或公开发布 GitHub Release。 +## 当前证据与废弃候选 -## 当前证据 +- 实现 PR #67、版本准备 PR #68 已合并;此次拆包修正仍待合并。 +- 旧候选 run `37480252872` 八平台构建及 smoke 虽通过,但 Linux x64 误含两套 NPU,单包 `577,384,672` bytes、解压 `1,455,176,275` bytes。**该候选不用于正式发布,须从拆包后的 main 重建。** +- 双 NPU 源码构建 run `37469626258` 通过;AMD 官方 SDK 已取得,20 桶实际编译,无 AMD 设备推理证据。 +- 原始 AMD SDK 身份见 `tools/npu/amdnpu-source.lock.json`;部署输入见 `tools/npu/amdnpu.lock.json`。约 508 MiB 的部署归档仍作为独立 AMD 支持包的构建输入,不进入普通包。 +- 13 个基础新 package identity 的空位检查已通过;两个新 NPU 支持包须独立发布。最终拆包候选的 tarball 和 run 在生成后补录。 -- PR #67 的 Linux native 与 workspace CI 均通过;这属于实现来源,不是 0.5.9 八平台发布结果。 -- 13 个新 package identity 的 npm 空位检查通过;加上复用的两个 preview 模型,release manifest 仍包含 15 包。 -- Intel+AMD Core/Node addon 已按 `LIGHT_OCR_VERSION=0.5.9` 重新配置并构建通过;版本闭包、lockfile 和脚本语法检查通过,未运行新的本地测试。实际 tarball、发布/晋升 run 和 registry integrity 尚未生成。 -- AMD 20 桶已实际编译,20 个原生库与 56 个库存文件已导入;原始 SDK、打包后运行库及模型哈希均已记录。本次没有执行 AMD 推理,不安排 NPU 真机验收。 +## 本地拆包构建证据 + +三个 addon(基础 CPU、独立 OpenVINO、独立 AMD)均已分别构建并完成 staging。基础库存仅含 CPU provider,无 NPU 目录,native 文件共 `33,091,890` bytes(此处不含正式 WebGPU/PDF 分发附件)。两个独立支持包已实际生成 tarball: + +| Package | Compressed bytes | Unpacked bytes | +| --- | ---: | ---: | +| `@arcships/light-ocr-amdnpu-linux-x64-gnu` | 548,609,874 | 1,390,267,314 | +| `@arcships/light-ocr-openvino-linux-x64-gnu` | 26,363,501 | 72,478,453 | + +这是本地拆包证据,不是新的八平台正式候选结果。未运行新的本地测试或真机验收。 ## 回滚 diff --git a/package-lock.json b/package-lock.json index ab67abc..994238b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1318,6 +1318,18 @@ "@arcships/light-ocr-linux-x64-musl": "0.5.9", "@arcships/light-ocr-win32-arm64": "0.5.9", "@arcships/light-ocr-win32-x64": "0.5.9" + }, + "peerDependencies": { + "@arcships/light-ocr-amdnpu-linux-x64-gnu": "0.5.9", + "@arcships/light-ocr-openvino-linux-x64-gnu": "0.5.9" + }, + "peerDependenciesMeta": { + "@arcships/light-ocr-amdnpu-linux-x64-gnu": { + "optional": true + }, + "@arcships/light-ocr-openvino-linux-x64-gnu": { + "optional": true + } } } } diff --git a/packages/light-ocr/README.md b/packages/light-ocr/README.md index fee5a85..816a898 100644 --- a/packages/light-ocr/README.md +++ b/packages/light-ocr/README.md @@ -308,3 +308,14 @@ console.log(modelProfile); Apache-2.0. The package also carries the applicable licenses and notices for the bundled PP-OCRv6 model, native runtimes, PDFium, and Noto Sans SC font. + +## Optional NPU support + +The default Small model bundle stays unchanged. AMD and OpenVINO are separate support packages and are never automatically installed with this package. On Linux x64 glibc, install one matching package explicitly: + +```bash +npm install @arcships/light-ocr-openvino-linux-x64-gnu@0.5.9 +# Or: npm install @arcships/light-ocr-amdnpu-linux-x64-gnu@0.5.9 +``` + +Then select `execution: { provider: 'openvino' }` or `execution: { provider: 'amdnpu' }` when creating the engine. Auto keeps the existing base policy. Vendor drivers are required; AMD contexts bind to Small 0.3.4. See the [NPU guide](https://github.com/arcships/light-ocr/blob/main/docs/npu-runtime-release.md). diff --git a/packages/runtime/README.md b/packages/runtime/README.md index 91b0db5..eb5041e 100644 --- a/packages/runtime/README.md +++ b/packages/runtime/README.md @@ -14,13 +14,21 @@ Use `@arcships/light-ocr` for stable Small, `@arcships/light-ocr-tiny` for the s ## NPU configuration -Starting with the prepared 0.5.9 native release, Linux x64 glibc packages include Intel OpenVINO in Auto ahead of WebGPU/CPU. The same Linux x64 release includes Ryzen AI 1.8 native libraries and 20 compiled BF16 contexts for Small 0.3.4. AMD is excluded from Auto; enable it explicitly: +The default install contains no AMD or OpenVINO libraries or compiled NPU models. Small keeps its existing locked model bundle. Install the matching support package separately: + +```bash +npm install @arcships/light-ocr-openvino-linux-x64-gnu@0.5.9 +# Or, for AMD STX/KRK and Small 0.3.4: +npm install @arcships/light-ocr-amdnpu-linux-x64-gnu@0.5.9 +``` ```js const engine = await createEngine({ bundlePath: '/absolute/model/bundle', - execution: { provider: 'amdnpu' }, + execution: { provider: 'amdnpu' }, // or 'openvino' }); ``` -These AMD contexts require the Small 0.3.4 recognition model and an installed Ryzen AI 1.8 STX/KRK driver stack. Other tiers require separately compiled contexts. Platforms without AMD payload report `unsupported_capability`. Explicit selection does not silently fall back. NPU shipping does not assert hardware qualification; `deviceValidated` stays false. +Both packages are optional peers, without automatic installation. Only an explicit provider selects their separate native addon. Auto uses the base package's existing WebGPU/Apple/CPU policy, even when support packages are installed. Explicit NPU selection never silently falls back if its package is absent. + +Vendor drivers are required on Linux x64 glibc. AMD contexts bind to Small 0.3.4; Tiny/Medium need separately compiled contexts. Hardware inference has not been qualified; `deviceValidated` stays false. diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 06fe74d..700272b 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -39,5 +39,17 @@ }, "scripts": { "test": "node --test test/*.test.cjs" + }, + "peerDependencies": { + "@arcships/light-ocr-openvino-linux-x64-gnu": "0.5.9", + "@arcships/light-ocr-amdnpu-linux-x64-gnu": "0.5.9" + }, + "peerDependenciesMeta": { + "@arcships/light-ocr-openvino-linux-x64-gnu": { + "optional": true + }, + "@arcships/light-ocr-amdnpu-linux-x64-gnu": { + "optional": true + } } } diff --git a/packages/runtime/src/index.cjs b/packages/runtime/src/index.cjs index e6a2757..88ffb2a 100644 --- a/packages/runtime/src/index.cjs +++ b/packages/runtime/src/index.cjs @@ -158,12 +158,15 @@ class OcrEngineImpl { } } -let nativeRuntime; +const nativeRuntimes = new Map(); async function createEngine(options) { try { const resolvedOptions = resolveCreateOptions(options); - if (!nativeRuntime) nativeRuntime = loadNative(); + const requested = resolvedOptions.execution?.provider; + const runtimeKey = ['openvino', 'amdnpu'].includes(requested) ? requested : 'default'; + if (!nativeRuntimes.has(runtimeKey)) nativeRuntimes.set(runtimeKey, loadNative(requested)); + const nativeRuntime = nativeRuntimes.get(runtimeKey); const nativeEngine = await nativeRuntime.binding.createEngine( resolvedOptions, nativeRuntime.runtimePolicy, diff --git a/packages/runtime/src/load-native.cjs b/packages/runtime/src/load-native.cjs index 09aab2b..9898e46 100644 --- a/packages/runtime/src/load-native.cjs +++ b/packages/runtime/src/load-native.cjs @@ -607,26 +607,44 @@ function validateNativeContract(binding, runtimePolicy) { } } -function loadNative() { +function loadNative(provider) { const development = resolveDevelopmentInput(); let input; if (development) { input = development; } else { - const packageName = platformPackage(); + const support = ['openvino', 'amdnpu'].includes(provider); + if (support && platformIdentity().id !== 'linux-x64') { + throw adapterError('unsupported_capability', `${provider} support requires Linux x64 glibc`); + } + const packageName = support + ? `@arcships/light-ocr-${provider}-linux-x64-gnu` + : platformPackage(); try { const binary = require.resolve(packageName); input = { binary, descriptor: path.join(path.dirname(binary), 'runtime-descriptor.json') }; } catch (cause) { throw adapterError( - 'package_load_failed', + support ? 'unsupported_capability' : 'package_load_failed', `Unable to locate ${packageName}`, - 'Reinstall @arcships/light-ocr without --omit=optional and verify that the current platform is supported.', + support ? `Install ${packageName} explicitly to enable ${provider}.` + : 'Reinstall @arcships/light-ocr without --omit=optional and verify that the current platform is supported.', cause, ); } } + if (!development && ['openvino', 'amdnpu'].includes(provider)) { + const manifestPath = path.resolve(path.dirname(input.binary), '../package.json'); + let manifest; + try { manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); } + catch (cause) { throw adapterError('package_load_failed', 'Invalid NPU support package manifest', manifestPath, cause); } + if (manifest.name !== `@arcships/light-ocr-${provider}-linux-x64-gnu` || + manifest.version !== require('./metadata.cjs').coreVersion) { + throw adapterError('package_load_failed', 'NPU support package must match the light-ocr core version', manifestPath); + } + } + if (!fs.existsSync(input.binary)) { throw adapterError('package_load_failed', 'Native addon is missing', input.binary); } diff --git a/tools/npm_release.py b/tools/npm_release.py index fc9ec39..ed23f89 100644 --- a/tools/npm_release.py +++ b/tools/npm_release.py @@ -610,6 +610,13 @@ def _webgpu_manifest(arguments: argparse.Namespace) -> dict[str, Any]: def stage_native(arguments: argparse.Namespace) -> None: + support_provider = getattr(arguments, 'npu_support_provider', None) + supplied_npu = [name for name in ('openvino', 'amdnpu') + if getattr(arguments, f'{name}_sdk_dir', None) is not None] + if supplied_npu and (supplied_npu != [support_provider] or arguments.platform_id != 'linux-x64'): + raise RuntimeError('NPU payloads must be staged as a separate provider support package') + if support_provider and supplied_npu != [support_provider]: + raise RuntimeError('support package requires exactly its own NPU SDK') platform = PLATFORMS[arguments.platform_id] build = arguments.build_dir.resolve() metadata = arguments.metadata_dir.resolve() @@ -1027,6 +1034,8 @@ def stage_workspace_package(workspace: str, output: Path) -> dict[str, Any]: "engines", "dependencies", "optionalDependencies", + "peerDependencies", + "peerDependenciesMeta", ) for field in copied_fields: if field in source_json: @@ -1217,6 +1226,9 @@ def assemble(arguments: argparse.Namespace) -> None: if not runtime_descriptor_path.is_file(): raise RuntimeError(f"runtime descriptor is missing for {platform_id}") runtime_descriptor = read_json(runtime_descriptor_path) + if any(name in runtime_descriptor.get('providers', {}) or (source / 'native' / name).exists() + for name in ('openvino', 'amdnpu')): + raise RuntimeError('default native packages must not contain AMD or OpenVINO payloads') validate_runtime_descriptor( runtime_descriptor, source, platform_id=platform_id, require_released=True ) diff --git a/tools/npu/package_support.py b/tools/npu/package_support.py new file mode 100644 index 0000000..047bc95 --- /dev/null +++ b/tools/npu/package_support.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +"""Package one NPU addon independently from the default npm install closure.""" +from __future__ import annotations +import argparse +from pathlib import Path +import sys +from types import SimpleNamespace +sys.path.insert(0, str(Path(__file__).resolve().parents[2])) +from tools import npm_release as release + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument('--provider', choices=['openvino', 'amdnpu'], required=True) + parser.add_argument('--build-dir', type=Path, required=True) + parser.add_argument('--metadata-dir', type=Path, required=True) + parser.add_argument('--sdk-dir', type=Path, required=True) + parser.add_argument('--output-dir', type=Path, required=True) + args = parser.parse_args() + provider = args.provider + name = f'@arcships/light-ocr-{provider}-linux-x64-gnu' + release.stage_native(SimpleNamespace(platform_id='linux-x64', build_dir=args.build_dir, + metadata_dir=args.metadata_dir, output_dir=args.output_dir, configuration='Release', + runtime_flavor='cpu', qualification_build=False, pdfium_dir=None, + openvino_sdk_dir=args.sdk_dir if provider == 'openvino' else None, + amdnpu_sdk_dir=args.sdk_dir if provider == 'amdnpu' else None, + npu_support_provider=provider)) + output = args.output_dir + (output / 'native-input.json').unlink() + package = release.common_package(name, release.CORE_VERSION, + f'Explicitly installed {provider} NPU support for light-ocr on Linux x64 glibc') + package.update({'main': './native/light_ocr_node.node', + 'exports': {'.': './native/light_ocr_node.node'}, 'os': ['linux'], 'cpu': ['x64'], + 'libc': ['glibc'], 'engines': {'node': '>=22.0.0'}, + 'files': ['native/', 'licenses/', 'qualification/', 'license-inventory.json', + 'sbom.spdx.json', 'artifact-hashes.json', 'README.md', 'LICENSE', 'NOTICE']}) + release.write_json(output / 'package.json', package) + release.add_project_files(output, f'''# {name} + +Install this package explicitly alongside `@arcships/light-ocr`. +It is excluded from the default dependency closure and contains a separate NPU addon. +Use `execution: {{ provider: "{provider}" }}` to select it. +Vendor drivers are required. Hardware inference has not been qualified. +''' + ('AMD contexts are bound to Small 0.3.4; Tiny/Medium require their own compiled contexts.\n' + if provider == 'amdnpu' else 'OpenVINO compiles the selected ONNX models through the installed NPU driver.\n')) + release.artifact_hashes(output, name, release.CORE_VERSION) + print(name) + + +if __name__ == '__main__': + main()