Skip to content

Migration to PyTorch #225

Description

@lfoppiano

DeLFT's TensorFlow/Keras foundation now rests on an brittle dependency combination for one of its core features (CRF sequence decoding), while the NLP ecosystem DeLFT depends on — HuggingFace Transformers — has standardized on PyTorch. This issue proposes migrating the framework to PyTorch to remove accumulated workaround debt, return to maintained dependencies, and align with where the ecosystem is heading.

Our CRF stack depends on a dead, partly-broken library (primary driver)

CRF decoding is central to DeLFT's sequence-labeling models, but our CRF support is held together by unmaintained code:

  • We pin tfa-nightly==0.23.0.dev20240415222534 (pyproject.toml) — a nightly snapshot of TensorFlow Addons, which reached end-of-life in May 2024. No further fixes will come.
  • The TF-Addons CRF has a known, unresolved correctness bug, documented in our own code as waiting on an upstream PR that was never merged (crf_wrapper_default.py:5-12).
  • Our hand-maintained fallback CRF (crf_layer.py, ~200 lines) has documented limits — "zero masking is not working with TF2" (crf_layer.py:8) — and uses deprecated tensorflow.compat.v1 APIs.
  • CRF training cannot run in graph mode; the trainer records the gradient failure as "no solution for the moment" (trainer.py:142-147).

PyTorch has maintained CRF implementations (e.g. pytorch-crf) with correct, first-class masking and decoding, letting us delete both the custom CRF and the nightly dependency.

The ecosystem we build on is PyTorch-first

DeLFT's transformer support (Transformer.py) sits on HuggingFace Transformers, which has made PyTorch its primary backend and is winding down TensorFlow/Flax support. Staying on TF means tracking a backend our key upstream is deprecating; migrating aligns us with the actively-developed path and a far larger pool of PyTorch research code and contributors.

We shed a large amount of version-fragility and workaround debt

Much of the current code works around TensorFlow rather than building features:

  • Both wrapper.py entry points set TF_USE_LEGACY_KERAS=1 to opt out of Keras 3, which broke us at TF 2.16.
  • All deprecation/future/user warnings are suppressed wholesale (wrapper.py:28-39) because deprecated APIs are pervasive.
  • convert_model.py exists solely to migrate weights across breaking TF/Keras versions.
  • An import-ordering hack prevents TF's CUDA 12 and PyTorch's CUDA 11 from colliding (wrapper.py:6-8).

The simplification is in what we delete, not in PyTorch being inherently easier to write.

Ease in maintenance

Maintaining one library instead of two should make everything easier for us. Most importantly we will not be able to update beyond tensorflow 2.17 wihtout breaking the CRF compatibility.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions