Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
## [Unreleased]

## [v4.8.3](https://github.com/OpenNMT/CTranslate2/releases/tag/v4.8.3) (2026-10-13)

### New features

* Support converting UMT5 models from Hugging Face Transformers
* Support converting UMT5 models from Hugging Face Transformers (#2103) by [@the-cross-art](https://github.com/the-cross-art)

### Fixes and improvements

* Support Transformer models where each layer has its own relative attention bias
* Support Transformer models where each layer has its own relative attention bias by [@the-cross-art](https://github.com/the-cross-art)
* Fix Windows ROCm Translator hangs and DLL loading (#2106) by [@0xDELUXA](https://github.com/0xDELUXA)
* Fix crashes when loading model files from Python file-like objects (#2110) by [@Purfview](https://github.com/Purfview)
* Upgrade pybind11 to 2.13.6 for CPython 3.14 allocator safety (#2108) by [@cepeter](https://github.com/cepeter)
* Guard exhausted candidates in CUDA TopK stage 2 (#2104) by [@mzggr0914](https://github.com/mzggr0914)
* Fix Windows shutdown deadlocks and memory leaks with the Ruy backend (#2076) by [@timo9378](https://github.com/timo9378)
* Add Clang ThreadSanitizer testing (#1986) by [@3manifold](https://github.com/3manifold)
* Improve ROCm wheel testing and release checks; upgrade build actions to Node.js 24 (#2112) by [@jordimas](https://github.com/jordimas)
* Add local CUDA and ROCm release validation with CI wheels and commit status reporting by [@jordimas](https://github.com/jordimas)


## [v4.8.2](https://github.com/OpenNMT/CTranslate2/releases/tag/v4.8.2) (2026-08-31)
Expand Down
29 changes: 29 additions & 0 deletions contributors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Release validation

1. Open a release PR and wait for CI to pass.
2. On each Linux x86-64 GPU machine, check out the PR head and build its native
tests locally. Install test dependencies, model data, GPU drivers, and runtime
libraries, including a GPU-compatible PyTorch. Authenticate with `gh auth login`
using an account permitted to download artifacts and write commit statuses.
3. Run the native and Python tests, including GPU tests:

```bash
bash tools/release-check.sh cuda
```

Replace `cuda` with `rocm` on the AMD machine.

The script finds the current branch's PR in the GitHub repository named by `origin`.
It checks that tracked files are clean and HEAD matches the PR, then
publishes `release/cuda` or `release/rocm` as pending, then success or failure.
It downloads the CUDA or ROCm wheel from the latest push CI run for that exact
commit. Wait for the wheel artifact to be uploaded before running validation.
The wheel is installed into a temporary environment that reuses your Python
dependencies; the environment is removed afterwards. Your installed CTranslate2
is left untouched. Native tests use your local build, since CI does not upload it.
The script requires a visible GPU and both test commands to pass.
Detailed output stays in the terminal.

Configure both statuses as required checks for release PRs. Re-run validation
for every new commit. Publish the validated artifacts after CI and both GPU
checks pass; validate again if the final release changes the tested code.
2 changes: 1 addition & 1 deletion python/ctranslate2/version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Version information."""

__version__ = "4.8.2"
__version__ = "4.8.3"
73 changes: 73 additions & 0 deletions tools/release-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env bash
# Usage: bash tools/release-check.sh cuda|rocm
set -euo pipefail
if (( $# != 1 )) || [[ $1 != cuda && $1 != rocm ]]; then
echo "Usage: bash tools/release-check.sh cuda|rocm" >&2
exit 2
fi
backend=$1
cd "$(git rev-parse --show-toplevel)"

if ! git diff HEAD --quiet; then
echo "Commit or stash changes to tracked files before validation." >&2
exit 1
fi
if git remote get-url upstream >/dev/null 2>&1; then
repo=$(git remote get-url upstream)
else
repo=$(git remote get-url origin)
fi
repo=${repo#*github.com[:/]}
repo=${repo%.git}
sha=$(git rev-parse HEAD)
branch=$(git branch --show-current)
pr=$(gh pr list --repo "$repo" --state open --head "$branch" --json number,headRefOid --jq ".[] | select(.headRefOid == \"$sha\") | .number" | head -n 1)
if [[ -z $pr ]]; then
echo "Local HEAD is not the head commit of an open PR for $branch in $repo." >&2
exit 1
fi
publish() {
gh api "repos/$repo/statuses/$sha" \
-f "state=$1" -f "context=release/$backend" >/dev/null
}
publish pending
state=failure
workdir=$(mktemp -d)
trap 'result=$?; rm -rf "$workdir"; publish "$state" || exit 1; exit "$result"' EXIT
artifact=python-wheels-Linux-auto64
[[ $backend == rocm ]] && artifact=rocm-python-wheels-Linux
run=${RELEASE_CHECK_RUN_ID:-}
if [[ -n $run ]]; then
artifacts=$(gh api --paginate "repos/$repo/actions/runs/$run/artifacts" --jq '.artifacts[] | select(.expired == false) | .name')
if [[ $'\n'"$artifacts"$'\n' != *$'\n'"$artifact"$'\n'* ]]; then
echo "CI run $run does not contain an available $artifact artifact." >&2
exit 1
fi
else
runs=$(gh run list --repo "$repo" --workflow ci.yml --commit "$sha" --limit 100 --json databaseId --jq '.[].databaseId')
for candidate in $runs; do
artifacts=$(gh api --paginate "repos/$repo/actions/runs/$candidate/artifacts" --jq '.artifacts[] | select(.expired == false) | .name')
if [[ $'\n'"$artifacts"$'\n' == *$'\n'"$artifact"$'\n'* ]]; then
run=$candidate
break
fi
done
fi
if [[ -z $run ]]; then
echo "No CI run for commit $sha contains an available $artifact artifact." >&2
exit 1
fi
echo "Downloading $artifact from https://github.com/$repo/actions/runs/$run"
gh run download "$run" --repo "$repo" --name "$artifact" --dir "$workdir/wheels"
python -m venv "$workdir/venv"
python="$workdir/venv/bin/python"
"$python" -m pip install -r python/tests/requirements.txt
"$python" -m pip install --force-reinstall --find-links "$workdir/wheels" ctranslate2
"$python" -I -c "import ctranslate2; print(ctranslate2.__file__); assert ctranslate2.get_cuda_device_count() > 0, 'No GPU available in the PR wheel; check drivers and runtime libraries'"
if [[ -x tests/ctranslate2_test ]]; then
tests/ctranslate2_test tests/data
else
echo "Skipping native tests: tests/ctranslate2_test is not built." >&2
fi
"$python" -I -m pytest -v python/tests/ --ignore=python/tests/test_fairseq.py --ignore=python/tests/test_opennmt_py.py --ignore=python/tests/test_opennmt_tf.py
state=success
Loading