Download src/tools/third_party_notices.py from CIIL/Anuvani-Diarization: direct link, hf CLI and curl.
- Browser
- Download file 7.07 kB
-
https://huggingface.co/CIIL/Anuvani-Diarization/resolve/main/src/tools/third_party_notices.py
- Command line
-
hf download hf://CIIL/Anuvani-Diarization/src/tools/third_party_notices.py
-
curl -L -o third_party_notices.py https://huggingface.co/CIIL/Anuvani-Diarization/resolve/main/src/tools/third_party_notices.py
7.07 kB
| # Copyright (c) 2026 The Anuvani-Diarization authors | |
| # SPDX-License-Identifier: MIT OR Apache-2.0 | |
| """Write THIRD_PARTY_NOTICES.md and LICENSES/crates/: what this project contains or links that others wrote. | |
| source env/canonical.sh && python3 tools/third_party_notices.py | |
| The Rust crates are the ones `cargo metadata --locked` resolves for the two shipped binaries (the wheel's extension | |
| `anuvani_diar._core`, from crates/diar-py, and the gateway, crates/diar-gateway), development-only dependencies left | |
| out; each crate's own licence files (LICENSE*, COPYING*, NOTICE*, UNLICENSE*) are copied from its source in the | |
| local cargo registry into LICENSES/crates/<name>-<version>/. The other sections are fixed text kept below; their | |
| licence texts are in LICENSES/third_party/ (and, for the wheel's bundled libraries, in the wheel's | |
| anuvani_diar/_libs/LICENSES/). Run it again after changing Cargo.lock. | |
| """ | |
| import json | |
| import shutil | |
| import subprocess | |
| from pathlib import Path | |
| PROJ = Path(__file__).resolve().parents[1] | |
| FILES = ("LICENSE", "LICENCE", "COPYING", "NOTICE", "UNLICENSE", "COPYRIGHT") | |
| HEAD = """# Third-party notices | |
| Anuvani-Diarization's code is licensed under MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`). It contains, ports | |
| or links work by others, listed here with their licences. The model weights have their own licences, set by the | |
| models they derive from (see the model card): the segmentation network is a fine-tuned derivative of | |
| `BUT-FIT/diarizen-wavlm-large-s80-md-v2` and is CC BY-NC 4.0 (non-commercial); the PLDA model (BUT Speech@FIT) and | |
| the speaker-embedding network (`pyannote/wespeaker-voxceleb-resnet34-LM`) are CC BY 4.0. | |
| ## Code copied or adapted into this project | |
| | Upstream | Licence | Where | Licence text | | |
| |---|---|---|---| | |
| | DiariZen (BUT Speech@FIT), commit 844f555 | MIT | the segmentation network's code, verbatim (`python/anuvani_diar/nn/seg/`; also the frozen release's `hf_port_poc/anuvani_diar_net/`); its VBx and clustering set-up, ported to Rust (`crates/diar-core`) | `LICENSES/third_party/DiariZen-MIT.txt` | | |
| | torchaudio 2.1.1 (Facebook, Inc.) | BSD-2-Clause | `kaldi.py` (fbank) and `resample.py`, verbatim; the wav2vec2 building blocks inside DiariZen's code | `LICENSES/third_party/torchaudio-BSD-2-Clause.txt` | | |
| | pyannote.audio 3.1.1, DiariZen's fork (CNRS) | MIT | the voiceprint network's fbank, forward and statistics pooling (`voiceprint.py`); window reconstruction and masks, ported to Rust | `LICENSES/third_party/pyannote-audio-MIT.txt` | | |
| | WeSpeaker (Shuai Wang), via pyannote.audio | Apache-2.0 | the voiceprint network's ResNet34 (`voiceprint.py`) | `LICENSES/third_party/Apache-2.0.txt` | | |
| | VBx (BUT Speech@FIT), via DiariZen's `diarizen/clustering/VBx.py` | Apache-2.0 | variational Bayes clustering, ported to Rust (`crates/diar-core/src/vbx.rs`) | `LICENSES/third_party/Apache-2.0.txt` | | |
| | SciPy 1.15.3 (SciPy Developers) | BSD-3-Clause | centroid-linkage AHC and pairwise distances, reimplemented in Rust to give SciPy's exact results | `LICENSES/third_party/scipy-LICENSE.txt` | | |
| | NumPy 1.26.4 (NumPy Developers) | BSD-3-Clause | numerical behaviour reproduced in Rust; its OpenBLAS build is bundled (below) | `LICENSES/third_party/numpy-LICENSE.txt` | | |
| | python-soundfile 0.14.0 (Bastian Bechtold) | BSD-3-Clause | the sequence of libsndfile calls `sf.read` makes, reproduced in Rust (`crates/diar-audio`) | `LICENSES/third_party/soundfile-LICENSE.txt` | | |
| ## Native libraries bundled in the wheel | |
| Copied unchanged from the numpy 1.26.4 and soundfile 0.14.0 wheels, each checked by sha256 when it loads; their | |
| licence texts are in the wheel (`anuvani_diar/_libs/LICENSES/`, index in its README.txt): | |
| | Library | Licence | | |
| |---|---| | |
| | OpenBLAS 0.3.23.dev (numpy 1.26.4's build) | BSD-3-Clause | | |
| | libgfortran 5 | GPL-3.0 with the GCC Runtime Library Exception 3.1 | | |
| | libquadmath 0 | LGPL-2.1-or-later | | |
| | libsndfile 1.2.2, with FLAC 1.4.3, Ogg 1.3, Vorbis 1.3.7, Opus 1.4, mpg123 1.32.3, LAME 3.100 | LGPL-2.1-or-later (libsndfile, mpg123, LAME); BSD-3-Clause (FLAC, Ogg, Vorbis, Opus) | | |
| libsndfile is LGPL: `ANUVANI_DIAR_SNDFILE` (with `ANUVANI_DIAR_SNDFILE_UNCHECKED=1`) runs the engine with another | |
| build of it (`docs/WHEEL.md`). The source of the LGPL libraries (libsndfile with its codecs and the script that built | |
| it; libquadmath, as the GCC source package it was built from) is in the model repository's `third_party_sources/`, | |
| whose README traces each binary to its source. | |
| ## Container images the serving kit builds | |
| `triton_inference/` builds two images on the user's machine; they are not distributed here. The Triton image starts | |
| from `nvcr.io/nvidia/tritonserver:24.10-py3` (NVIDIA Deep Learning Container License) and installs PyTorch and | |
| torchaudio 2.1.1 (BSD-3-Clause and BSD-2-Clause) and NVIDIA's cuBLAS and NVRTC wheels (NVIDIA proprietary licence); | |
| the service image starts from `ubuntu:22.04` and installs FastAPI and Pydantic (MIT), Starlette and Uvicorn | |
| (BSD-3-Clause) and python-multipart (Apache-2.0) (`triton_inference/service/requirements.txt`). | |
| ## Rust crates compiled into the wheel and the gateway | |
| """ | |
| def crates(): | |
| meta = json.loads(subprocess.run(["cargo", "metadata", "--format-version", "1", "--locked"], cwd=PROJ, | |
| capture_output=True, text=True, check=True).stdout) | |
| pk = {p["id"]: p for p in meta["packages"]} | |
| ws = set(meta["workspace_members"]) | |
| nodes = {n["id"]: n for n in meta["resolve"]["nodes"]} | |
| stack = [i for i in ws if pk[i]["name"] in ("diar-py", "diar-gateway")] | |
| seen = set() | |
| while stack: | |
| for d in nodes[stack.pop()]["deps"]: | |
| if {k["kind"] for k in d["dep_kinds"]} - {"dev"} and d["pkg"] not in seen: | |
| seen.add(d["pkg"]) | |
| stack.append(d["pkg"]) | |
| return sorted((pk[i] for i in seen if i not in ws), key=lambda p: (p["name"], p["version"])) | |
| def main(): | |
| out = PROJ / "LICENSES" / "crates" | |
| if out.exists(): | |
| shutil.rmtree(out) | |
| rows = [] | |
| for p in crates(): | |
| src = Path(p["manifest_path"]).parent | |
| dst = out / f"{p['name']}-{p['version']}" | |
| texts = [] | |
| for f in sorted(src.iterdir()): | |
| if f.is_file() and f.name.upper().startswith(FILES): | |
| dst.mkdir(parents=True, exist_ok=True) | |
| shutil.copyfile(f, dst / f.name) | |
| texts.append(f.name) | |
| where = f"`LICENSES/crates/{dst.name}/` ({', '.join(texts)})" if texts else "no licence file in the crate's source" | |
| rows.append(f"| {p['name']} | {p['version']} | {p['license'] or '(see crate)'} | {where} |") | |
| body = (HEAD + f"{len(rows)} crates, resolved by `cargo metadata --locked` (`tools/third_party_notices.py`):\n\n" | |
| "| Crate | Version | Licence | Licence files |\n|---|---|---|---|\n" + "\n".join(rows) + "\n") | |
| (PROJ / "THIRD_PARTY_NOTICES.md").write_text(body) | |
| print(f"THIRD_PARTY_NOTICES.md: {len(rows)} crates; {sum(1 for r in rows if 'no licence file' in r)} without a licence file") | |
| if __name__ == "__main__": | |
| main() | |