A Comprehensive Guide to Training Named Entity Recognition Models with Hugging Face
Named Entity Recognition, or NER for short, is a fundamental task in Natural Language Processing (NLP) that involves identifying and categorizing named entities in text into predefined categories such as person names, organizations, locations, medical codes, time expressions, quantities, monetary values, percentages, etc. NER is a key component of many NLP applications including:
- Information extraction: Automatically extracting structured information from unstructured text
- Question answering: Locating the answer to a question in a given passage
- Chatbots: Understanding the intent behind user queries
- Text summarization: Identifying the key entities being discussed
- Content recommendation: Tagging articles with relevant entities to improve recommendations
- Anonymization: Detecting and redacting sensitive information like personal names from text
Given the wide-ranging applications, it‘s no surprise that NER has been an active area of research in both academia and industry. In recent years, deep learning approaches have achieved state-of-the-art performance on NER benchmarks, outperforming traditional statistical and rule-based methods.
One of the most popular NLP frameworks that provides state-of-the-art models for NER is Hugging Face. Hugging Face is an open-source library that provides thousands of pretrained models to perform tasks on texts such as classification, information extraction, question answering, summarization, translation, text generation, etc. It supports TensorFlow 2.0 and PyTorch and provides APIs to easily download and use state-of-the-art NLP models.
In this tutorial, we‘ll walk through the process of training a custom NER model using Hugging Face‘s Transformers library and PyTorch. By the end, you‘ll know how to:
- Prepare an NER dataset in the format required by Hugging Face
- Initialize a pre-trained transformer model and tokenizer
- Define an NER head on top of the pre-trained model
- Fine-tune the model on our custom dataset
- Evaluate the model‘s performance
- Use the trained model to make predictions on new text
- Deploy the model in a production environment
We‘ll be using Python 3 and PyTorch 1.8 or higher. You can install the required dependencies with:
!pip install transformers torch
Preparing the Dataset
The first step is to prepare our NER dataset in the format required by the Hugging Face Datasets library. The most common format is the CoNLL format, where each line contains a word followed by its label, and sentences are separated by a blank line. Here‘s an example:
John B-PER
works O
for O
Google B-ORG
in O
New B-LOC
York I-LOC
. O
He O
joined O
the O
company O
in O
2010 B-DATE
. O
In this example, we have two sentences with entities labeled as person (PER), organization (ORG), location (LOC), and date. The B- prefix indicates the beginning of an entity, while I- indicates the continuation of an entity. O indicates a word that is not part of any entity.
If your data is in a different format, you‘ll need to write a script to convert it to the CoNLL format. You can also use the pre-defined NER datasets in the Hugging Face Datasets library, such as CoNLL-2003 or OntoNotes 5.0.
For this tutorial, we‘ll use the CoNLL-2003 dataset which contains newswire text annotated with four entity types: persons (PER), locations (LOC), organizations (ORG), and miscellaneous (MISC). We can load the dataset as follows:
from datasets import load_dataset
dataset = load_dataset("conll2003")
This will download the CoNLL-2003 dataset and cache it locally for future use. The dataset contains a training set, validation set, and test set. We can access them as follows:
train_dataset = dataset["train"]
valid_dataset = dataset["validation"]
test_dataset = dataset["test"]
Initializing the Model and Tokenizer
Next, we need to initialize a pre-trained transformer model and tokenizer. Hugging Face provides a wide range of pre-trained models that we can use for NER, such as BERT, RoBERTa, XLNet, etc. For this tutorial, we‘ll use the bert-base-cased model which is a 12-layer BERT model trained on cased English text.
from transformers import BertTokenizerFast, BertForTokenClassification
model_name = "bert-base-cased"
tokenizer = BertTokenizerFast.from_pretrained(model_name)
model = BertForTokenClassification.from_pretrained(model_name, num_labels=len(label_list))
Here, we first initialize the tokenizer using BertTokenizerFast.from_pretrained() which downloads the vocabulary and configuration files for the specified model. We then initialize the model using BertForTokenClassification.from_pretrained() which downloads the pre-trained weights and initializes a token classification head on top of the BERT model. The num_labels argument specifies the number of entity types in our dataset, which is 5 (4 entity types + 1 for non-entity tokens).
Fine-tuning the Model
Now that we have our model and data ready, we can fine-tune the model on our dataset. We‘ll use the Trainer class from the Hugging Face Transformers library which handles the training loop, logging, checkpointing, and evaluation.
First, we need to define our training arguments:
from transformers import TrainingArguments
training_args = TrainingArguments(
output_dir=‘./results‘, # output directory
num_train_epochs=3, # total number of training epochs
per_device_train_batch_size=16, # batch size per device during training
per_device_eval_batch_size=64, # batch size for evaluation
warmup_steps=500, # number of warmup steps for learning rate scheduler
learning_rate=2e-5, # learning rate
weight_decay=0.01, # strength of weight decay
logging_dir=‘./logs‘, # directory for storing logs
logging_steps=10,
)
Here, we specify the output directory to save the model checkpoints, the number of training epochs, batch sizes for training and evaluation, learning rate, etc.
Next, we create a Trainer object and pass in our model, training arguments, training and validation datasets, and data collator:
from transformers import Trainer
trainer = Trainer(
model=model, # the instantiated Transformers model to be trained
args=training_args, # training arguments, defined above
train_dataset=train_dataset, # training dataset
eval_dataset=valid_dataset, # evaluation dataset
data_collator=data_collator, # data collator
)
The data collator is responsible for batching the input examples together and applying any necessary preprocessing. We can use the DataCollatorForTokenClassification class from the Transformers library which handles everything for us:
from transformers import DataCollatorForTokenClassification
data_collator = DataCollatorForTokenClassification(tokenizer)
Finally, we can start training our model:
trainer.train()
This will fine-tune the BERT model on our CoNLL-2003 dataset for 3 epochs and save the best checkpoint to the output_dir specified in the training arguments.
Evaluating the Model
After training, we can evaluate our model‘s performance on the test set. We‘ll use the evaluate() method from the Trainer class which computes the loss and any specified metrics on the test set.
results = trainer.evaluate(test_dataset)
print(results)
This will print out the test loss and any evaluation metrics specified in the compute_metrics argument of the Trainer. By default, Hugging Face provides an evaluate_conll2003() function which computes the precision, recall, and F1 score for each entity type as well as the overall scores.
Hugging Face also provides a predict() method that we can use to get the model‘s predictions on new text. For example:
text = "John works for Google in New York."
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
outputs = model(**inputs)
predictions = outputs.logits.argmax(dim=-1).tolist()[0]
labels = [label_list[i] for i in predictions]
print(list(zip(text.split(), labels)))
This will output:
[(‘John‘, ‘B-PER‘), (‘works‘, ‘O‘), (‘for‘, ‘O‘), (‘Google‘, ‘B-ORG‘), (‘in‘, ‘O‘), (‘New‘, ‘B-LOC‘), (‘York‘, ‘I-LOC‘), (‘.‘, ‘O‘)]
Deploying the Model
Once we have a trained NER model that performs well, we may want to deploy it as an API endpoint or integrate it into a larger application. Hugging Face provides several options for deploying models:
-
Hugging Face Inference API: This is the easiest way to deploy a model as an API endpoint. We simply need to create a model repository on the Hugging Face Hub and push our trained model. Hugging Face will automatically build a Docker image and host the API endpoint for us.
-
Docker: We can build a custom Docker image that includes our trained model and any necessary dependencies. We can then deploy the image to a container orchestration platform like Kubernetes or Amazon ECS.
-
Serverless: We can deploy our model as a serverless function using platforms like AWS Lambda, Google Cloud Functions, or Azure Functions. This allows us to scale our inference workload without managing any infrastructure.
For more details on deploying Hugging Face models, check out the official documentation.
Conclusion
In this tutorial, we learned how to train a custom NER model using Hugging Face‘s Transformers library and the CoNLL-2003 dataset. We walked through the steps of preparing the dataset, initializing the model and tokenizer, fine-tuning the model, evaluating its performance, and making predictions on new text.
NER is a powerful technique that enables us to extract structured information from unstructured text. Some potential use cases of NER include:
- Extracting entities like people, places, and organizations from news articles or social media posts to gain insights into trends and events.
- Identifying medical entities like drugs, diseases, and procedures from clinical notes to aid in medical research and patient care.
- Detecting sensitive information like names, addresses, and social security numbers in documents to ensure compliance with data privacy regulations.
As NLP continues to advance, we can expect to see even more sophisticated NER models that can handle more complex and domain-specific entity types. Some exciting research directions include:
- Few-shot and zero-shot learning for NER, which enables models to recognize new entity types with minimal or no labeled data
- Multimodal NER, which leverages information from images and other modalities to improve entity recognition
- Cross-lingual NER, which allows transferring knowledge from high-resource languages to low-resource languages
With the help of open-source libraries like Hugging Face, it‘s easier than ever to experiment with state-of-the-art NLP models and build powerful applications. I hope this tutorial has given you a good starting point for your own NER projects. Happy coding!