Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 23 additions & 4 deletions .github/workflows/huggingface-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,21 @@ jobs:
# nemotron-ocr-v1 needs nvcc/CUDA headers to build its extension.
# Build with Python 3.12 to match upstream package constraints and
# avoid producing an extension for the wrong Python ABI.
runs-on: ubuntu-latest
# Matrix across x86_64 and aarch64 so the wheel works on ARM hosts
# (e.g. DGX Spark) as well as conventional x86 machines.
runs-on: ${{ matrix.platform.runner }}
strategy:
fail-fast: false
matrix:
platform:
- runner: ubuntu-latest
cuda_image: nvidia/cuda:13.0.0-devel-ubuntu24.04
arch: x86_64
- runner: ubuntu-24.04-arm
cuda_image: nvidia/cuda:13.0.0-devel-ubuntu24.04
arch: aarch64
container:
# Build extension with CUDA 13 toolchain (nvcc/headers from devel image).
image: nvidia/cuda:13.0.0-devel-ubuntu24.04
image: ${{ matrix.platform.cuda_image }}
steps:
- name: Install system deps (git, lfs, build tools)
shell: bash
Expand Down Expand Up @@ -201,6 +212,13 @@ jobs:
skip_existing_flag="--skip-existing"
fi

# The upstream build script checks ARCH to skip x86-only SIMD
# flags (e.g. -mavx2) that are invalid on aarch64.
arch_env_arg=""
if [[ "$(uname -m)" == "aarch64" ]]; then
arch_env_arg="--build-env ARCH=arm64"
fi

python --version
python ci/scripts/nightly_build_publish.py \
--repo-id "nemotron-ocr-v1" \
Expand All @@ -215,6 +233,7 @@ jobs:
--venv-pip-install "torchvision==0.24.1" \
--build-env "BUILD_CPP_EXTENSION=1" \
--build-env "BUILD_CPP_FORCE=1" \
${arch_env_arg} \
${upload_flag} \
--repository-url "${repo_url}" \
--token-env "${token_env}" \
Expand Down Expand Up @@ -253,5 +272,5 @@ jobs:
if: always()
uses: actions/upload-artifact@v4
with:
name: dist-nemotron-ocr-v1
name: dist-nemotron-ocr-v1-${{ matrix.platform.arch }}
path: dist-out/nemotron-ocr-v1/*
29 changes: 17 additions & 12 deletions ci/scripts/nightly_build_publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Behavior:
- Clones a HF git repo with Git LFS smudge disabled (so large weights are not downloaded).
- Attempts to append a PEP 440 dev version suffix (YYYYMMDD) to pyproject.toml or setup.cfg.
- Attempts to append a PEP 440 dev version suffix (YYYYMMDDHHmmss) to pyproject.toml or setup.cfg.
- Builds sdist + wheel via `python -m build`.
- Optionally uploads to (Test)PyPI via twine.

Expand Down Expand Up @@ -36,12 +36,18 @@ def _write_text(path: Path, text: str) -> None:
path.write_text(text, encoding="utf-8")


def _nightly_suffix_yyyymmdd() -> str:
# Allow overriding for reproducibility.
forced = os.environ.get("NIGHTLY_DATE_YYYYMMDD")
def _nightly_suffix() -> str:
"""Return a PEP 440 dev suffix that is unique per build.

Uses ``YYYYMMDDHHmmss`` so multiple builds on the same calendar day
each receive a distinct, monotonically increasing version.
The ``NIGHTLY_DATE_SUFFIX`` (or legacy ``NIGHTLY_DATE_YYYYMMDD``) env
var can override the value for reproducible builds.
"""
forced = os.environ.get("NIGHTLY_DATE_SUFFIX") or os.environ.get("NIGHTLY_DATE_YYYYMMDD")
if forced:
return forced
return _dt.datetime.now(_dt.UTC).strftime("%Y%m%d")
return _dt.datetime.now(_dt.UTC).strftime("%Y%m%d%H%M%S")


def _venv_python(venv_dir: Path) -> Path:
Expand Down Expand Up @@ -80,17 +86,16 @@ def _ensure_venv(venv_dir: Path, *, system_site_packages: bool) -> Path:
return py


def _pep440_nightly(base_version: str, yyyymmdd: str) -> str:
def _pep440_nightly(base_version: str, suffix: str) -> str:
"""
Convert a base version to a nightly dev version.
Examples:
1.2.3 -> 1.2.3.dev20260127
1.2.3+local -> 1.2.3.dev20260127
1.2.3 -> 1.2.3.dev20260127031517
1.2.3+local -> 1.2.3.dev20260127031517
"""
base = base_version.split("+", 1)[0].strip()
# If already has a .dev segment, replace it to keep it monotonic daily.
base = re.sub(r"\.dev\d+$", "", base)
return f"{base}.dev{yyyymmdd}"
return f"{base}.dev{suffix}"


def _patch_pyproject_version(repo_dir: Path) -> bool:
Expand All @@ -105,7 +110,7 @@ def _patch_pyproject_version(repo_dir: Path) -> bool:
return False

old_version = m.group(1)
new_version = _pep440_nightly(old_version, _nightly_suffix_yyyymmdd())
new_version = _pep440_nightly(old_version, _nightly_suffix())
if new_version == old_version:
return False

Expand All @@ -127,7 +132,7 @@ def _patch_setup_cfg_version(repo_dir: Path) -> bool:
return False

old_version = m.group(1).strip().strip('"').strip("'")
new_version = _pep440_nightly(old_version, _nightly_suffix_yyyymmdd())
new_version = _pep440_nightly(old_version, _nightly_suffix())
if new_version == old_version:
return False

Expand Down
Loading