Skip to main content

Tibert

Tibert is a transformers-compatible reproduction from the paper End-to-end Neural Coreference Resolution with several modifications. Among these:

It can be installed with pip install tibert.

Documentation

Simple Prediction Example

Here is an example of using the simple prediction interface:

from tibert import BertForCoreferenceResolution, predict_coref_simple
from tibert.utils import pprint_coreference_document
from transformers import BertTokenizerFast

model = BertForCoreferenceResolution.from_pretrained(
    "compnet-renard/bert-base-cased-literary-coref-v2"
)
tokenizer = BertTokenizerFast.from_pretrained("bert-base-cased")

annotated_doc = predict_coref_simple(
    "Sli did not want the earpods. He didn't like them.", model, tokenizer
)

pprint_coreference_document(annotated_doc)

results in:

>>> (0 Sli ) did not want the earpods. (0 He ) didn't like them.

Batched Predictions for Performance

A more advanced prediction interface is available:

from transformers import BertTokenizerFast
from tibert import predict_coref, BertForCoreferenceResolution

model = BertForCoreferenceResolution.from_pretrained(
    "compnet-renard/bert-base-cased-literary-coref-v2"
)
tokenizer = BertTokenizerFast.from_pretrained("bert-base-cased")

documents = [
    "Sli did not want the earpods. He didn't like them.",
    "Princess Liana felt sad, because Zarth Arn was gone. The princess went to sleep.",
]

annotated_docs = predict_coref(documents, model, tokenizer, batch_size=2)

for doc in annotated_docs:
    pprint_coreference_document(doc)

results in:

>>> (0 Sli ) did not want the earpods . (0 He ) didn't like them .

>>> (0 Princess Liana ) felt sad , because (1 Zarth Arn ) was gone . (0 The princess) went to sleep .

Using Coreference Chains

The coreference chains predicted can be accessed using the .coref_chains attribute:

annotated_doc = predict_coref_simple(
    "Princess Liana felt sad, because Zarth Arn was gone. The princess went to sleep.",
    model,
    tokenizer
)
print(annotated_doc.coref_chains)

>>>[[Mention(tokens=['The', 'princess'], start_idx=11, end_idx=13), Mention(tokens=['Princess', 'Liana'], start_idx=0, end_idx=2)], [Mention(tokens=['Zarth', 'Arn'], start_idx=6, end_idx=8)]]

Hierarchical Merging

Hierarchical merging allows to reduce RAM usage and computations when performing inference on long documents. To do so, the user provides the text cut in chunks. The model will perform prediction for chunks, which means the long document wont be taken at once into memory. Then, hierarchical merging will try to merge chunk predictions. This allow scaling to arbitrarily large documents. See Coreference in Long Documents using Hierarchical Entity Merging for more details.

Hierarchical merging can be used as follows:

from tibert import BertForCoreferenceResolution, predict_coref
from tibert.utils import pprint_coreference_document
from transformers import BertTokenizerFast

model = BertForCoreferenceResolution.from_pretrained(
    "compnet-renard/bert-base-cased-literary-coref-v2"
)
tokenizer = BertTokenizerFast.from_pretrained("bert-base-cased")

chunk1 = "Princess Liana felt sad, because Zarth Arn was gone."
chunk2 = "She went to sleep."

annotated_doc = predict_coref(
    [chunk1, chunk2], model, tokenizer, hierarchical_merging=True
)

pprint_coreference_document(annotated_doc)

This results in:

>>>(1 Princess Liana ) felt sad , because (0 Zarth Arn ) was gone . (1 She ) went to sleep .

Even if the mentions Princess Liana and She are not in the same chunk, hierarchical merging still resolves this case correctly.

Training a model

Aside from the tibert.train.train_coref_model function, it is possible to train a model from the command line. Training a model requires installing the sacred library. Here is the most basic example:

python -m tibert.run_train with\
       dataset_path=/path/to/litbank/repository\
       out_model_dir=/path/to/output/model/directory

The following parameters can be set (taken from ./tibert/run_train.py config function):

Parameter Default Value
batch_size 1
epochs_nb 30
dataset_name "litbank"
dataset_path "~/litbank"
mentions_per_tokens 0.4
antecedents_nb 350
max_span_size 10
mention_scorer_hidden_size 3000
sents_per_documents_train 11
mention_loss_coeff 0.1
bert_lr 1e-5
task_lr 2e-4
dropout 0.3
segment_size 128
encoder "bert-base-cased"
out_model_dir "~/tibert/model"
checkpoint None

One can monitor training metrics by adding run observers using command line flags - see sacred documentation for more details.

Method

We reimplemented the model from Lee et al., 2017 from scratch, but used BERT as the encoder as in Joshi et al., 2019. We do not use higher order inference as in Lee et al., 2018 since it was found to be not necessarily useful by Xu and Choi, 2020.

Singletons

Unfortunately, the framework from Lee et al., 2017 cannot represent singletons. This is because the authors were working on the OntoNotes dataset, where singletons are not annotated. We wanted to work on Litbank, so we had to find a way to represent singletons.

We opted to do as in Xu and Choi, 2021: we consider mention with a high enough mention scores as singletons, even when they are in no clusters. To force the model to learn proper mention scores, we add an auxiliary loss on mention score (as in Xu and Choi, 2021). To counter dataset imbalance between positive and negative mentions, we opt to compute a weighted loss instead of performing sampling.

Additional Features

Several work make use of additional features. For now, only the distance between spans is implemented.

Results

The following table presents the results we obtained on Litbank by training this model. We evaluate on 10% of Litbank documents, each of which consists of ~2000 tokens. The split column indicate whether documents were split in blocks of 512 tokens. The HM coumns indicates whether we use hierarchical merging. Time is measured on cpu inference.

compnet-renard/bert-base-cased-literary-coref

Dataset Base model split HM MUC B3 CEAF BLANC LEA time (m:s)
Litbank bert-base-cased no no 75.03 60.66 48.71 62.96 32.84 01:40
Litbank bert-base-cased yes no 73.84 49.14 47.88 48.41 27.63 00:57
Litbank bert-base-cased yes yes 74.54 59.30 46.98 62.69 42.46 01:36

compnet-renard/bert-base-cased-literary-coref-v2

Dataset Base model split HM MUC B3 CEAF BLANC LEA time (m:s)
Litbank bert-base-cased no no 78.24 62.38 54.15 62.55 35.18 02:45
Litbank bert-base-cased yes no 75.30 51.76 52.83 51.23 29.44 01:59
Litbank bert-base-cased yes yes 76.12 61.50 53.36 63.97 44.07 02:36

Citation

If you use this software in a research project, you can cite Tibert as follows:

@Misc{tibert,
  author = {Amalvy, A. and Labatut, V. and Dufour, R.},
  title = {Tibert},
  year  = {2023},
  url   = {https://github.com/CompNet/Tibert},
}

Metadata

Release files for tibert 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tibert 0.6.0
File Size Uploaded Provenance
tibert-0.6.0.tar.gz 48.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for tibert 0.6.0
File Interpreter ABI Platform
tibert-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 95.9 kB

Release files / tibert-0.6.0.tar.gz

Download URL tibert-0.6.0.tar.gz
Size 48.5 kB
Tags Source
SHA-256 checksum
How to use checksums
148ab2abbd917d9d88a66981b67b427a46a32d554784278bc641a257b314ce9f
BLAKE2b-256 checksum
How to use checksums
680ebb3ae9e6b4aee3ad6039131cfb489b7253ae7a15268716457336ee9bbf96
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"44","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / tibert-0.6.0-py3-none-any.whl

Download URL tibert-0.6.0-py3-none-any.whl
Size 47.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8565ba192d3fe52fc3b86abf23937ed02c2e7a27057496ad7dd9b17a53e8a868
BLAKE2b-256 checksum
How to use checksums
3214329be44a29e7c88342d4dbb6a69e9e80c0bc74df3705fd6b8ca9715c9d0a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"44","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for tibert 0.6.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page