Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e04644e
switch dependency from tensorflow-cpu to torch (only cpu variant for …
osma Jan 8, 2026
2d3e434
NN ensemble basic functionality implemented using PyTorch
osma Jan 12, 2026
da479eb
add pytorch and python version to NN model; remove model metadata fun…
osma Jan 13, 2026
e629963
enable selecting PyTorch CPU or CUDA (12.8) variant through extras
osma Jan 15, 2026
3784155
use torch-cpu extra in CI/CD and Dockerfile to select CPU-only PyTorc…
osma Jan 15, 2026
541f2af
define dependency group 'all' as a substitute for '--all-extras' and …
osma Jan 16, 2026
e3fc7f9
drop torch-cpu from 'all' group as it is not needed
osma Jan 16, 2026
ff8c692
add progress bar (using tqdm) for NN ensemble training loop
osma Jan 16, 2026
1660273
calculate nDCG after every training epoch (using torchmetrics package)
osma Jan 16, 2026
bf0cba0
specify num_workers and weight_decay parameters
osma Jan 16, 2026
85057cd
cleanup
osma Jan 16, 2026
fb38ef8
remove unnecessary TensorFlow log level adjustment
osma Jan 16, 2026
9681ab3
remove test for TF log level setting
osma Jan 16, 2026
faf3de7
adjust PyTorch model to better match old Keras model
osma Jan 21, 2026
311a29c
fix test that broke
osma Jan 21, 2026
1437d43
switch to BCELoss (requires clamping output values)
osma Jan 21, 2026
49b7d48
implement ndcg calculation inline instead of relying on memory-heavy …
osma Jan 23, 2026
23bdcd6
fix ndcg calculation bug; remove Keras-emulating hidden layer initial…
osma Jan 23, 2026
099e08d
switch to AdamW optimizer, seems to converge slightly faster
osma Jan 23, 2026
9f35d09
drop unnecessary line
osma Jan 23, 2026
4ef0600
avoid allocating unnecessary variable n_labels
osma Jan 23, 2026
f949e1c
use a Conv1d layer instead of torch.mean for averaging input
osma Jan 23, 2026
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
4 changes: 2 additions & 2 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ jobs:
# Selectively install the optional dependencies for some Python versions
# For Python 3.10:
if [[ ${{ matrix.python-version }} == '3.10' ]]; then
uv sync --extra nn --extra omikuji --extra yake --extra voikko --extra stwfsa;
uv sync --extra nn --extra torch-cpu --extra omikuji --extra yake --extra voikko --extra stwfsa;
fi
# For Python 3.11:
if [[ ${{ matrix.python-version }} == '3.11' ]]; then
Expand All @@ -106,7 +106,7 @@ jobs:
fi
# For Python 3.12:
if [[ ${{ matrix.python-version }} == '3.12' ]]; then
uv sync --extra nn --extra fasttext --extra yake --extra stwfsa --extra voikko --extra spacy;
uv sync --extra nn --extra torch-cpu --extra fasttext --extra yake --extra stwfsa --extra voikko --extra spacy;
# download the small English pretrained spaCy model needed by spacy analyzer
uv run python -m spacy download en_core_web_sm --upgrade-strategy only-if-needed
fi
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
LABEL org.opencontainers.image.authors="[email protected]"
SHELL ["/bin/bash", "-c"]

ARG optional_dependencies="voikko fasttext nn omikuji yake spacy stwfsa"
ARG optional_dependencies="voikko fasttext nn omikuji yake spacy stwfsa torch-cpu"

# Install system dependencies needed at runtime:
RUN apt-get update && apt-get upgrade -y && \
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ Create a virtual environment and install dependencies:

uv sync

By default development dependencies are included. Use option `--extra` to install dependencies for selected optional features (`--extra "extra1 extra2"` for multiple extras), or install all of them with `--all-extras`. By default the virtual environment directory is `.venv` under the project directory.
By default development dependencies are included. Use the option `--extra` to install dependencies for selected optional features (`--extra foo --extra bar` for multiple extras). There are also special extras for selecting the PyTorch backend for those optional features (`nn`) that depend on PyTorch: `--extra torch-cpu` will use the CPU backend and `--extra torch-cu128` will use the CUDA 12.8 backend. For a full set of extras with CPU-only PyTorch, use `uv sync --group all --extra torch-cpu`.

By default the virtual environment directory is `.venv` under the project directory.

You can run Annif in one of two ways:

Expand Down
19 changes: 0 additions & 19 deletions annif/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
def create_flask_app(config_name: str | None = None) -> Flask:
"""Create a Flask app to be used by the CLI."""

_set_tensorflow_loglevel()

app = Flask(__name__)
config_name = _get_config_name(config_name)
logger.debug(f"creating flask app with configuration {config_name}")
Expand Down Expand Up @@ -93,20 +91,3 @@ def _get_config_name(config_name: str | None) -> str:
else:
config_name = "annif.default_config.ProductionConfig" # pragma: no cover
return config_name


def _set_tensorflow_loglevel():
"""Set TensorFlow log level based on Annif log level (--verbosity/-v
option) using an environment variable. INFO messages by TF are shown only on
DEBUG (or NOTSET) level of Annif."""
annif_loglevel = logger.getEffectiveLevel()
tf_loglevel_mapping = {
0: "0", # NOTSET
10: "0", # DEBUG
20: "1", # INFO
30: "1", # WARNING
40: "2", # ERROR
50: "3", # CRITICAL
}
tf_loglevel = tf_loglevel_mapping[annif_loglevel]
os.environ.setdefault("TF_CPP_MIN_LOG_LEVEL", tf_loglevel)
4 changes: 1 addition & 3 deletions annif/backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ def _nn_ensemble() -> Type[AnnifBackend]:

return nn_ensemble.NNEnsembleBackend
except ImportError:
raise ValueError(
"Keras and TensorFlow not available, cannot use " + "nn_ensemble backend"
)
raise ValueError("PyTorch not available, cannot use nn_ensemble backend")


def _omikuji() -> Type[AnnifBackend]:
Expand Down
Loading