-
-
Notifications
You must be signed in to change notification settings - Fork 200
feat: riscv64 prebuilt binaries #615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
afc96cd
44e844c
362c8ff
4342c57
aa9fd7f
be14bfe
bf8fe22
d3163b4
22adbb7
6528b6e
e76c8bb
ac456d2
b5df301
686ca7a
283c117
eb277c8
7958a86
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -75,13 +75,37 @@ jobs: | |
| - name: "macOS arm64" | ||
| os: macos-26 | ||
| artifact: "mac-arm64" | ||
| - name: "Ubuntu riscv64" | ||
| os: ubuntu-24.04-riscv | ||
| artifact: "linux-riscv64" | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-node@v4 | ||
| if: matrix.config.artifact != 'linux-riscv64' | ||
| with: | ||
| node-version: "20" | ||
|
|
||
| - name: Install Node.js (riscv64 unofficial build) | ||
| if: matrix.config.artifact == 'linux-riscv64' | ||
| run: | | ||
| set -e | ||
| need=24.10.0 | ||
| if command -v node >/dev/null 2>&1; then | ||
| cur="$(node -p 'process.versions.node')" | ||
| if [ "$(printf '%s\n%s\n' "$need" "$cur" | sort -V | head -1)" = "$need" ]; then | ||
| echo "Using preinstalled Node.js v$cur at $(command -v node)" | ||
| exit 0 | ||
| fi | ||
| echo "Preinstalled Node.js v$cur is older than $need; installing unofficial build" | ||
| fi | ||
| NODE_VER=v24.16.0 | ||
| curl -fsSL -o /tmp/node.tar.xz "https://unofficial-builds.nodejs.org/download/release/${NODE_VER}/node-${NODE_VER}-linux-riscv64.tar.xz" | ||
| mkdir -p "$HOME/node" | ||
| tar -xJf /tmp/node.tar.xz -C "$HOME/node" --strip-components=1 | ||
| echo "$HOME/node/bin" >> "$GITHUB_PATH" | ||
| "$HOME/node/bin/node" --version | ||
|
|
||
|
Comment on lines
+89
to
+108
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe updating to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. setup-node@v6 won't help here, unfortunately. It pulls official Node binaries from nodejs.org/dist, and there are no riscv64 builds there. Same gap as setup-python and setup-uv. The only place shipping riscv64 Node is unofficial-builds.nodejs.org, which is what this step grabs. I don't think a config flag changes that, but if you know one I'll happily switch. The jump to Node 24 is a separate reason: Node 20's npm 10.8.2 hits "set.delete is not a function" during npm ci on riscv64, and a couple of devDeps want node >= 24.10. The built binary still targets the Node 20 N-API.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about the - uses: actions/setup-node@v6
with:
mirror: "https://unofficial-builds.nodejs.org/download/release/"
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea, I tested it on the riscv64 runner. It half-works. With That tarball does exist on unofficial-builds, so setup-node's mirror fallback isn't resolving riscv64; it just leans on whatever's cached on the runner. The curl step always pulls the pinned version, so I'd rather keep it. Happy to switch if you know a config that fixes the resolution.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dug a little bit deeper and it seems that the reason it failed is because this file doesn't include any riscv64 entries. For now I think we can proceed with a custom step, and it might be a good idea to gate it to only execute if nodejs v24 isn't already present; @luhenry said nodejs v24 is preinstalled on
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. The step now prefers the preinstalled Node when it's 24.10+ and only downloads the unofficial build as a fallback. Thanks for tracking down the manifest gap, that explains the setup-node failure. Adding riscv64 to actions/node-versions is a good idea; I'll look into that as a separate PR so setup-node can work here directly. |
||
| - name: Download build artifact | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
|
|
@@ -131,6 +155,19 @@ jobs: | |
|
|
||
| cmake --version | ||
|
|
||
| # llama.cpp's ggml-cpu uses the RVV _Float16 (zvfh) vector intrinsics, | ||
| # which only exist in GCC 14+. The runner defaults to GCC 13, so make | ||
| # gcc-14/g++-14 the default compilers (same as upstream build-riscv). | ||
| - name: Install dependencies on Ubuntu riscv64 | ||
| if: matrix.config.name == 'Ubuntu riscv64' | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y cmake build-essential ninja-build libtbb-dev gcc-14 g++-14 retry | ||
| sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 100 | ||
| sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 100 | ||
| cmake --version | ||
| gcc --version | ||
|
|
||
| - name: Install Cuda 13.1 on Windows (1) | ||
| if: matrix.config.name == 'Windows (1)' | ||
| uses: Jimver/cuda-toolkit@v0.2.30 | ||
|
|
@@ -207,9 +244,16 @@ jobs: | |
| timeout-minutes: 300 | ||
| env: | ||
| ARTIFACT_NAME: ${{ matrix.config.artifact }} | ||
| ELECTRON_SKIP_BINARY_DOWNLOAD: "1" | ||
| run: | | ||
| npm ci | ||
|
|
||
| if [ "$ARTIFACT_NAME" = "linux-riscv64" ]; then | ||
| # The unofficial riscv64 Node runtime intermittently throws internal | ||
| # TypeErrors during npm ci (e.g. "key.match is not a function") | ||
| retry --times=3 npm ci | ||
| else | ||
| npm ci | ||
| fi | ||
|
|
||
| npx zx -y <<'EOF' | ||
|
|
||
| async function getLatestNodeVersions(maxDate) { | ||
|
|
@@ -275,6 +319,8 @@ jobs: | |
| await buildBinary("x64", ["--gpu", "false"]); | ||
| } else if (process.env.ARTIFACT_NAME === "mac-arm64") { | ||
| await buildBinary("arm64", ["--gpu", "metal"]); | ||
| } else if (process.env.ARTIFACT_NAME === "linux-riscv64") { | ||
| await buildBinary("riscv64", ["--gpu", "false"]); | ||
| } | ||
|
|
||
| // move binaries to bins | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| /dist |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| MIT License | ||
|
|
||
| Copyright (c) 2024 Gilad S. | ||
|
|
||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
|
|
||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
|
|
||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # [`node-llama-cpp`](https://github.com/withcatai/node-llama-cpp) | ||
| This is a prebuilt binary package for [`node-llama-cpp`](https://github.com/withcatai/node-llama-cpp) for Linux riscv64. | ||
|
|
||
| Do not install this package directly. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| { | ||
| "name": "@node-llama-cpp/linux-riscv64", | ||
| "version": "0.1.0", | ||
| "description": "Prebuilt binary for node-llama-cpp for Linux riscv64", | ||
| "main": "dist/index.js", | ||
| "type": "module", | ||
| "files": [ | ||
| "dist/", | ||
| "bins/", | ||
| "package.json", | ||
| "README.md", | ||
| "LICENSE" | ||
| ], | ||
| "exports": { | ||
| ".": { | ||
| "import": "./dist/index.js", | ||
| "node": "./dist/index.js", | ||
| "default": "./dist/index.js" | ||
| } | ||
| }, | ||
| "engines": { | ||
| "node": ">=20.0.0" | ||
| }, | ||
| "os": [ | ||
| "linux" | ||
| ], | ||
| "cpu": [ | ||
| "riscv64" | ||
| ], | ||
| "libc": [ | ||
| "glibc" | ||
| ], | ||
| "scripts": { | ||
| "prebuild": "rimraf ./dist ./tsconfig.tsbuildinfo", | ||
| "build": "tsc --build tsconfig.json --force", | ||
| "prewatch": "rimraf ./dist ./tsconfig.tsbuildinfo", | ||
| "watch": "tsc --build tsconfig.json --watch --force", | ||
| "clean": "rm -rf ./node_modules ./dist ./tsconfig.tsbuildinfo" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/withcatai/node-llama-cpp.git" | ||
| }, | ||
| "author": "Gilad S.", | ||
| "license": "MIT", | ||
| "preferUnplugged": true, | ||
| "bugs": { | ||
| "url": "https://github.com/withcatai/node-llama-cpp/issues" | ||
| }, | ||
| "homepage": "https://node-llama-cpp.withcat.ai", | ||
| "devDependencies": { | ||
| "typescript": "^5.2.2" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import path from "path"; | ||
| import {fileURLToPath} from "url"; | ||
| import fs from "node:fs/promises"; | ||
|
|
||
| const __dirname = path.dirname(fileURLToPath(import.meta.url)); | ||
| const binsDir = path.join(__dirname, "..", "bins"); | ||
| const packageVersion: string = (JSON.parse(await fs.readFile(path.join(__dirname, "..", "package.json"), "utf8"))).version; | ||
|
|
||
| export function getBinsDir() { | ||
| return { | ||
| binsDir, | ||
| packageVersion | ||
| }; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| { | ||
| "compilerOptions": { | ||
| "lib": ["es2022"], | ||
| "module": "node16", | ||
| "target": "es2022", | ||
| "esModuleInterop": true, | ||
| "noImplicitAny": true, | ||
| "noImplicitReturns": true, | ||
| "noImplicitThis": true, | ||
| "noImplicitOverride": true, | ||
| "removeComments": false, | ||
| "allowSyntheticDefaultImports": true, | ||
| "forceConsistentCasingInFileNames": true, | ||
| "noFallthroughCasesInSwitch": true, | ||
| "skipLibCheck": true, | ||
| "moduleResolution": "node16", | ||
| "resolveJsonModule": false, | ||
| "strictNullChecks": true, | ||
| "isolatedModules": true, | ||
| "noEmit": false, | ||
| "outDir": "./dist", | ||
| "strict": true, | ||
| "sourceMap": false, | ||
| "composite": false, | ||
| "declaration": false, | ||
| "stripInternal": true | ||
| }, | ||
| "files": [ | ||
| "./src/index.ts" | ||
| ], | ||
| "include": [ | ||
| "./src" | ||
| ] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is node installed on the
ubuntu-24.04-riscvmachines. Why do you need to do that?