sentencepiece: build wheels for riscv64 - #165
Conversation
|
@gounthar I've been updating the development guide and I've also pushed some other workflows for matplotlib and cffi since your PRs were opened. Can you refactor and update them so we can review again? Keep in mind, we want the workflows to closely mirror the upstream workflows as much as possible, so prefer that over similarity with our existing workflows when possible. |
Refs #164 Signed-off-by: Bruno Verachten <gounthar@gmail.com>
Match the documented default matrix (3.11 through 3.14t); numpy's 3.12+ floor is the exception, not the rule. Signed-off-by: Bruno Verachten <gounthar@gmail.com>
Copy python/tools alongside python/test so gen_stubs_test can import gen_stubs, and drop the ad-hoc pytest ignores to mirror upstream's 'pytest -v {project}/test'.
Signed-off-by: Bruno Verachten <gounthar@gmail.com>
Reshape the workflow after google/sentencepiece's own .github/workflows/wheel.yml instead of build-numpy.yml, and follow the current development guide. Build side: run cibuildwheel from the python/ directory the way upstream does, including the data/*.bin copy into src/sentencepiece/package_data that the tests rely on, and pin cibuildwheel to 3.4.0, the version upstream pins in requirements/cibuildwheel.txt. That makes the project's own [tool.cibuildwheel] table usable as-is, so the CIBW_TEST_SOURCES and CIBW_TEST_COMMAND overrides are no longer needed. Upstream's hash-pinned requirements files are not reused since they also pin twine's dependency chain, which would be compiled from source on the runner. Add upstream's free-threading test job, running against 3.14t rather than 3.13t, and pin the manylinux_riscv64 image so the in-container test dependencies resolve against our registry rather than building numpy from an sdist. Trim the matrix to the default 3.12 to 3.14t set, and switch publishing to the publish-wheels action with the permissions it needs, dropping the branch check that the dry-run logic now handles. Signed-off-by: Bruno Verachten <gounthar@gmail.com>
16c4c77 to
56ffa0a
Compare
|
|
Thanks, that makes sense. I had built this one by copying build-numpy.yml, which is exactly the habit you're pointing at. Pushed a rebase plus a rewrite that starts from google/sentencepiece's own wheel.yml instead. The part that changed the most: I pinned cibuildwheel to 3.4.0, the version upstream pins in requirements/cibuildwheel.txt. With that version the project's own [tool.cibuildwheel] table works as-is, so the CIBW_TEST_SOURCES and CIBW_TEST_COMMAND overrides I had are gone. I didn't reuse their requirements files wholesale though, since base.txt also pins twine's chain (cffi, cryptography) and those would get compiled from source on the runner. Installing cibuildwheel alone at their pinned version felt like the smaller deviation, but if you'd rather see the hash-pinned install kept I can try it. I also picked up the data/*.bin copy into src/sentencepiece/package_data that upstream does before building, which I had simply missed the first time. And their free-threading job, running against 3.14t rather than 3.13t to match the default matrix. That last one is the piece I'm least sure about: it installs sentencepiece[test] and pytest-run-parallel for 3.14t, and I haven't checked whether protobuf resolves there on riscv64. If the trigger run goes red on it I'll just drop the job. Two things I'd like your read on. I dropped upstream's sdist round-trip (build_sdist.sh, then building a wheel from the sdist) and the twine check that validates it, going by the guide's rule about sdist builds that nothing consumes. On native riscv64 that round-trip is a second full C++ build per Python version, which is why I leaned that way, but it does mean we lose the twine --strict check on the wheels. And I made publish need the free-threading job, which is stricter than what pillow, cffi and numpy do. Both are easy to put back if you'd rather I matched the existing workflows. zstandard gets the same treatment next, along with the QEMU point justeph raised on the upstream PR. You've been shaping these conventions for a while, so if I've read the guide the wrong way somewhere, say so and I'll redo it. |
|
@gounthar I don't think we need the On a related note, the way this workflow sets up the matrix should be tweaked - I think it'd be better if you used |
|
Both make sense, though there's one thing I want to flag before I delete the free-threading job. On the matrix: agreed. I'll move to CIBW_SKIP in On free-threading: you're right that the wheel is covered. I checked cibuildwheel 3.4.0 and the gate in The part that goes away with the job is The same job passed on the earlier run that morning, so it's intermittent, which is roughly what I'd expect from a real race. I haven't checked whether it reproduces on x86 3.13t, so I can't tell you yet if this is riscv64-specific or just upstream free-threading being upstream free-threading. Happy to drop the job as you asked. Chasing upstream thread-safety probably isn't this repo's job. I'd just rather you made that call knowing it caught a crash. Want me to file an issue with the trace before removing it, or just take it out? |
Replaces the per-version job matrix with a single cibuildwheel invocation, matching upstream's wheel.yml shape so the two are easier to compare. Version selection now lives in CIBW_SKIP, which drops cp39, cp310 and cp311. This serializes the build on one riscv64 runner rather than spreading it across four. The four jobs took 28 to 30 minutes each in parallel, so expect roughly two hours wall instead of forty minutes, in exchange for holding a single runner. Also drops CIBW_ENABLE: cpython-freethreading, which was doing nothing here. cibuildwheel 3.4.0 only gates cp313t behind it, and the build produces cp314t either way. The four per-version artifacts become one, so the free-threading job now downloads that artifact by name and lets uv resolve the cp314t wheel out of it. Signed-off-by: Bruno Verachten <gounthar@gmail.com>
That test difference is a good observation. I would file an issue and see if they get back to you quickly. Best-case, it gets triaged and there's a patch to backport. We want to build wheels in a way that avoids bogged down chasing edge case issues, but we also need to make sure that they're going to work for users. Regarding the long build time, that's OK if we're confident it will succeed. I wonder if we could propose a similar parallelized wheel build upstream, bringing them in-line with what's done here? |
Adds
build-sentencepiece.ymlso sentencepiece riscv64 wheels build on the nativeubuntu-24.04-riscvrunner via cibuildwheel, and publish to the GitLab index onmain.This is the build workflow that the auto-generated #157 asks for ("No build workflow found at
.github/workflows/build-sentencepiece.yml").sentencepieceis already listed inci_scripts/packages.txt, so no manifest change is needed here.Shape
Mirrors
build-numpy.yml:google/sentencepieceat the requested tag (submodules: true, the C++ core is vendored)python/subdirectory viapackage-dir, since that is wheresetup.py/pyproject.tomllivecp312,cp313,cp314,cp314tmainand reuses the sharedpublish-to-gitlabactionWheels are also tested inline: cibuildwheel installs each freshly built wheel into an isolated venv and runs the package's own pytest suite against it (
CIBW_TEST_SOURCES+CIBW_TEST_COMMAND). Two files are skipped:gen_stubs_test.pyimports a repo-level helper that is not part of the copied test tree, andclean_sentencepiece_test_manual.pyis a manual cleanup script rather than a pytest module.Verification
Built and tested on a native riscv64 board (BananaPi BPI-F3), cp312, cibuildwheel 4.1.0,
manylinux_2_39_riscv64:produced
sentencepiece-0.2.2-cp312-cp312-manylinux_2_39_riscv64.whl.Refs #164
Trigger: sentencepiece:0.2.2