DeLFT: A Keras and TensorFlow Framework for Sequence Labeling and Text Classification
a Deep Learning Framework for Text https://delft.readthedocs.io/
At a glance
- What is it?
- DeLFT wraps RNN and transformer architectures behind one API for NER, information extraction and comment classification, with an emphasis on rich text and small model files. Its 0.4.x line is a deliberate break from 0.3.x: TensorFlow 2.17, tf_keras, CUDA 12.1 and converted caches.
- Who is it for?
- Adopt DeLFT if you need sequence labeling or classification over rich text and want RNN and transformer models behind one API, and you can accept the 0.4.x migration work. Do not adopt it if you only need a single transformer fine-tune, since the framework's value is in its task coverage and evaluation harness, not in replacing HuggingFace.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 14 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem DeLFT targets: text that is not a clean sentence
Most deep learning work in NLP assumes the input is a plain sequence of tokens. DeLFT starts from the opposite assumption. Its README states that it targets rich text, where tokens carry layout information such as font and style, positions inside structured documents, and other lexical or symbolic context. The stated reason is that text usually arrives from large PDF or HTML documents rather than as pre-segmented sentences or paragraphs, and that contextual features of this kind are useful.
That framing determines who the project is for. If your pipeline already produces clean sentence splits and you are fine-tuning one transformer per task, DeLFT's rich text machinery is overhead. If you are extracting entities from scholarly PDFs, or classifying comments where the surrounding structure matters, the input model matches the problem. The README also names a second purpose: reproducibility and benchmarking, by implementing several reference models for sequence labeling and classification so that reported results can be validated under the same conditions and criteria. A third stated purpose is production use, with the README describing optimized performance and integration possibilities. Those three goals pull in different directions, and the release history shows the tension.
One API over RNNs, transformers and categorical features
The README describes a variety of architectures and tasks exposed through the same API and input formats, covering both RNN and transformer models. HuggingFace transformers are integrated as Keras layers, so a BERT or RoBERTa model is not a separate code path from a recurrent model. Categorical features get generic support across several architectures, which is the mechanism behind the rich text claim: layout and positional attributes enter the model as categorical inputs rather than being flattened into the token string.
Two design choices are worth separating. First, dynamic data generators mean the training data does not have to sit entirely in memory, and static pre-trained embeddings can be loaded and managed at unlimited volume. Second, word embeddings are removed from the RNN models. The README gives a concrete number: the toxic comment classifier dropped from 230 MB with embeddings to 1.8 MB. It further states that in practice all DeLFT models are under 2 MB, except the Ontonotes 5.0 NER model at 4.7 MB. That is a real trade-off, not a free win. Small RNN checkpoints are cheap to ship and to load in a Java process, but they depend on embeddings supplied at runtime, so the embedding files remain part of your deployment. The transformer path does not get that size reduction.
The evaluation framework is the other half of the design. The README lists standard metrics for sequence labeling and classification tasks, plus n-fold cross validation. If you are comparing two architectures, that harness is the reason to use DeLFT rather than assembling your own training loop.
Installation and the CUDA 12.1 constraint
The README gives two install paths from PyPI. On macOS, pip install delft. On Linux with CUDA 12.1, pip install "delft[gpu]" --extra-index-url https://download.pytorch.org/whl/cu121.
The Linux split exists for a specific reason. The base pip install delft already pulls TensorFlow with NVIDIA CUDA libraries as transitive dependencies, roughly 2 GB according to the README. The [gpu] extra adds PyTorch built against CUDA 12.1. Torch is no longer included in the base install on Linux because torch ships against CUDA 12.4 while TensorFlow 2.17 requires CUDA 12.1, and the two conflict. If you install the base package on a Linux GPU host and then add torch yourself, you can reintroduce that conflict. The README states that GPU or GPUs are required for decent training time, and gives hardware examples: a GeForce GTX 1050 Ti with 4 GB works for RNN models and BERT or RoBERTa base, a GeForce GTX 1080 Ti with 11 GB handles BERT large including training at modest batch size, and multiple GPUs are supported for training and inference. Those are the README's examples, not measured results.
Python 3.10 or 3.11 is the supported range for the 0.4.x line, tested with TensorFlow 2.17. Python 3.8 and 3.9 are no longer supported. The README also mentions a --wandb flag for Weights & Biases experiment tracking and SLURM scripts for distributed training, though it does not document their configuration.
Migrating from 0.3.x: three conversion utilities, not one
The 0.4.x line is a breaking release, and the migration surface is larger than a dependency bump. Keras imports moved from tensorflow.keras to the standalone tf_keras package, and TensorFlow 2.17.1 with tf_keras 2.17.0 is now required. The README states plainly that pre-trained model weights from 0.3.4 are not directly compatible, but can be converted without retraining:
python -m delft.utilities.convert_model --input <old-model-dir> --output <new-model-dir> --verify
The converter rebuilds the architecture from the saved config.json, remaps weights from the old HDF5 file into the fresh model, and writes a new weights file. Flags matter here: --redownload-tokenizer when the saved tokenizer is incompatible with the current transformers version, --force-partial to allow partial conversion when some weights cannot be matched, and --dry-run to inspect without writing. The existence of --force-partial is the honest signal that conversion can fail partway.
Embeddings are a separate migration. LMDB caches now store raw float32 bytes instead of pickle-serialized objects, which the README says enables Java interoperability for GROBID and improves performance. Existing caches must be converted:
python -m delft.utilities.convert_lmdb_embeddings --input <old-lmdb-path> --output <new-lmdb-path>
ELMo support is removed entirely. The use_ELMo parameter is gone from all application scripts and configurations, and the README directs users to transformer models or static embeddings such as GloVe and fastText. If your configuration files reference use_ELMo, they will not load. That is a hard boundary, not a deprecation warning.
Where DeLFT is the wrong tool
The framework assumes you want its training and evaluation loop. If your task is a single classification problem over plain sentences, a direct transformers fine-tune with the Trainer API is less machinery, and you avoid the TensorFlow 2.17 plus CUDA 12.1 pinning that DeLFT imposes on your environment. DeLFT's value appears when you need several tasks and architectures under one input format, or when you need the n-fold cross validation harness.
The model size claim also has an edge. The sub-2 MB figures apply to RNN models without embeddings. The README does not claim the same for transformer-based models, and BERT large is discussed in terms of GPU memory, not checkpoint size. If disk or memory footprint is your reason for choosing DeLFT, confirm which architecture you intend to ship before relying on that number.
There is a second limitation in what the material does not say. The README describes rich text and categorical features but does not document the input format, the configuration keys, or the application scripts in the excerpt provided. The documentation site is referenced as the place for installation, usage and model details. Anyone evaluating DeLFT has to read delft.readthedocs.io before writing a data pipeline, because the README alone does not specify how layout features are encoded. The README is also truncated mid-sentence in the Linux installation note, so the full caveats around the base install are not visible here.
Finally, the release cadence is worth noting without reading anything into it. v1.0.0, v1.0.1 and v1.1.0 all landed within roughly five weeks of each other, and the last push to master is dated 2026-09-02. Frequent patch releases after a major version bump are normal for a migration of this size, but it also means the 1.1.x line is young.
The alternative: GROBID for the Java side, plain transformers for the Python side
The README names GROBID as a native Java integration of DeLFT via JEP. That is the closest thing to a direct alternative in the material, and the difference is architectural rather than algorithmic. GROBID is a document-parsing system for scholarly literature; it embeds DeLFT through JEP so that Python model inference runs inside a JVM process. The LMDB change to raw float32 bytes exists to serve that path. If you are processing PDFs and want entity extraction without running a separate Python service, GROBID is the integration point, and DeLFT is the model layer underneath it.
On the Python side, the comparison is with using HuggingFace transformers directly. DeLFT integrates transformers as Keras layers, so the underlying models can be the same. The difference is what surrounds them: DeLFT adds the shared input format for rich text, the categorical feature support, the dynamic data generators, the embedding management, and the evaluation metrics with cross validation. Choosing plain transformers means writing or sourcing each of those yourself. Choosing DeLFT means accepting its TensorFlow and CUDA constraints and its migration utilities as part of your build.
Licence and the cost of staying current
DeLFT is Apache-2.0, which permits commercial use and modification with the usual attribution and notice requirements. The README does not discuss model weights or pre-trained embeddings separately, so if you plan to redistribute a converted checkpoint or an embedding cache, check the terms attached to the source data and the embedding files you used. This is not legal advice; the licence file and the provenance of each artifact are what you need to read.
Maintenance cost is dominated by the dependency pins. TensorFlow 2.17.1, tf_keras 2.17.0, transformers 4.48, torch 2.5.1, numpy 1.26.4, scikit-learn 1.6.1 and pandas 2.2.3 are the versions the README lists for this line. TensorFlow's CUDA requirement of 12.1 against torch's 12.4 is the constraint most likely to break a shared environment, which is why the Linux extras split exists. Upgrading TensorFlow later will pull the CUDA requirement with it and may invalidate the tf_keras pairing.
The upgrade path itself is mechanical but not free. Every 0.3.x checkpoint and every LMDB embedding cache needs a conversion run, and the --force-partial flag exists because some weight mappings may not resolve. Budget for a verification pass on your own evaluation set after conversion, since the README states the converter can verify but does not promise that a partial conversion preserves accuracy.
Editorial conclusion
Adopt DeLFT if you need sequence labeling or classification over rich text and want RNN and transformer models behind one API, and you can accept the 0.4.x migration work. Do not adopt it if you only need a single transformer fine-tune, since the framework's value is in its task coverage and evaluation harness, not in replacing HuggingFace. Before committing, verify that your existing 0.3.4 weights convert with python -m delft.utilities.convert_model --verify, that your LMDB caches convert with python -m delft.utilities.convert_lmdb_embeddings, and that your CUDA driver matches the 12.1 requirement.
Community notes