Tuning a base Language model on the IMDB dataset
 

Introduction

In this tutorial we will be showing an end-to-end example of fine-tuning a Transformer language model on a custom dataset in DataFrame format.

By the end of this you should be able to:

  1. Build a dataset with the LanguageModelDatasets class, and their DataLoaders
  2. Build a LanguageModelTuner quickly, find a good learning rate, and train with the One-Cycle Policy
  3. Save that model away, to be used with deployment or other HuggingFace libraries
  4. Apply inference using both the Tuner available function as well as with the EasyTextGenerator class within AdaptNLP

Installing the Library

This tutorial utilizies the latest AdaptNLP version, as well as parts of the fastai library. Please run the below code to install them:

!pip install adaptnlp -U

(or pip3)

Getting the Dataset

First we need a dataset. We will use the fastai library to download the IMDB_SAMPLE dataset, a subset of IMDB Movie Reviews.

from fastai.data.external import URLs, untar_data

URLs holds a namespace of many data endpoints, and untar_data is a function that can download and extract any data from a given URL.

Combining both, we can download the data:

data_path = untar_data(URLs.IMDB_SAMPLE)

If we look at what was downloaded, we will find a texts.csv file:

data_path.ls()
(#1) [Path('/root/.fastai/data/imdb_sample/texts.csv')]

This is our data we want to use. We should now open the csv in pandas to generate our DataFrame object:

import pandas as pd
df = pd.read_csv(data_path/'texts.csv')

Let's look at our data

df.head()
label text is_valid
0 negative Un-bleeping-believable! Meg Ryan doesn't even look her usual pert lovable self in this, which normally makes me forgive her shallow ticky acting schtick. Hard to believe she was the producer on this dog. Plus Kevin Kline: what kind of suicide trip has his career been on? Whoosh... Banzai!!! Finally this was directed by the guy who did Big Chill? Must be a replay of Jonestown - hollywood style. Wooofff! False
1 positive This is a extremely well-made film. The acting, script and camera-work are all first-rate. The music is good, too, though it is mostly early in the film, when things are still relatively cheery. There are no really superstars in the cast, though several faces will be familiar. The entire cast does an excellent job with the script.<br /><br />But it is hard to watch, because there is no good end to a situation like the one presented. It is now fashionable to blame the British for setting Hindus and Muslims against each other, and then cruelly separating them into two countries. There is som... False
2 negative Every once in a long while a movie will come along that will be so awful that I feel compelled to warn people. If I labor all my days and I can save but one soul from watching this movie, how great will be my joy.<br /><br />Where to begin my discussion of pain. For starters, there was a musical montage every five minutes. There was no character development. Every character was a stereotype. We had swearing guy, fat guy who eats donuts, goofy foreign guy, etc. The script felt as if it were being written as the movie was being shot. The production value was so incredibly low that it felt li... False
3 positive Name just says it all. I watched this movie with my dad when it came out and having served in Korea he had great admiration for the man. The disappointing thing about this film is that it only concentrate on a short period of the man's life - interestingly enough the man's entire life would have made such an epic bio-pic that it is staggering to imagine the cost for production.<br /><br />Some posters elude to the flawed characteristics about the man, which are cheap shots. The theme of the movie "Duty, Honor, Country" are not just mere words blathered from the lips of a high-brassed offic... False
4 negative This movie succeeds at being one of the most unique movies you've seen. However this comes from the fact that you can't make heads or tails of this mess. It almost seems as a series of challenges set up to determine whether or not you are willing to walk out of the movie and give up the money you just paid. If you don't want to feel slighted you'll sit through this horrible film and develop a real sense of pity for the actors involved, they've all seen better days, but then you realize they actually got paid quite a bit of money to do this and you'll lose pity for them just like you've alr... False

We will find that there is a label, some text, and a is_valid boolean, which determines if a row is part of the training or the validation set

Now that we've downloaded some data, let's pick a viable model to train with

Picking a Model with the Hub

AdaptNLP has a HFModelHub class that allows you to communicate with the HuggingFace Hub and pick a model from it, as well as a namespace HF_TASKS class with a list of valid tasks we can search by.

Let's try and find one suitable for sequence classification.

First we need to import the class and generate an instance of it:

from adaptnlp import HFModelHub, HF_TASKS
hub = HFModelHub()

Next we can search for a model:

models = hub.search_model_by_task(HF_TASKS.TEXT_GENERATION)

Let's look at a few:

models[:10]
[Model Name: distilgpt2, Tasks: [text-generation],
 Model Name: gpt2-large, Tasks: [text-generation],
 Model Name: gpt2-medium, Tasks: [text-generation],
 Model Name: gpt2-xl, Tasks: [text-generation],
 Model Name: gpt2, Tasks: [text-generation],
 Model Name: openai-gpt, Tasks: [text-generation],
 Model Name: transfo-xl-wt103, Tasks: [text-generation],
 Model Name: xlnet-base-cased, Tasks: [text-generation],
 Model Name: xlnet-large-cased, Tasks: [text-generation]]

These are models specifically tagged with the text-generation tag, so you may not see a few models you would expect such as bert_base_cased.

We'll use that first model, distilgpt2:

model = models[0]
model
Model Name: distilgpt2, Tasks: [text-generation]

Now that we have picked a model, let's use the data API to prepare our data

Each task has a high-level data wrapper around the TaskDatasets class. In our case this is the LanguageModelDatasets class:

from adaptnlp import LanguageModelDatasets

There are multiple different constructors for the LanguageModelDatasets class, and you should never call the main constructor directly.

We will be using from_dfs:

LanguageModelDatasets.from_dfs[source]

LanguageModelDatasets.from_dfs(train_df:DataFrame, text_col:str, tokenizer_name:str, block_size:int=128, masked_lm:bool=False, valid_df:DataFrame=None, split_func:callable=None, split_pct:float=0.1, tokenize_kwargs:dict={}, auto_kwargs:dict={})

Builds LanguageModelDatasets from a DataFrame or file path

Parameters:

  • train_df : <class 'pandas.core.frame.DataFrame'>

    A Pandas Dataframe

  • text_col : <class 'str'>

    The name of the text column

  • tokenizer_name : <class 'str'>

    The name of the tokenizer

  • block_size : <class 'int'>, optional

    The size of each block

  • masked_lm : <class 'bool'>, optional

    Whether the language model is a MLM

  • valid_df : <class 'pandas.core.frame.DataFrame'>, optional

    An optional validation DataFrame

  • split_func : <built-in function callable>, optional

    Optionally a splitting function similar to RandomSplitter

  • split_pct : <class 'float'>, optional

    What % to split the df between training and validation

  • tokenize_kwargs : <class 'dict'>, optional

    kwargs for the tokenize function

  • auto_kwargs : <class 'dict'>, optional

    kwargs for the AutoTokenizer.from_pretrained constructor

Anything you would normally pass to the tokenizer call (such as max_length, padding) should go in tokenize_kwargs, and anything going to the AutoTokenizer.from_pretrained constructor should be passed to the auto_kwargs.

In our case we only have a train_df, and since we are training a language model, we want to split the data 90/10 (which is the default)

Also, we will set a block_size of 128, and it is not a masked language model:

dsets = LanguageModelDatasets.from_dfs(
    train_df=df,
    text_col='text',
    tokenizer_name=model.name,
    block_size=128,
    masked_lm=False
)
No value for `max_length` set, automatically adjusting to the size of the model and including truncation
Sequence length set to: 1024




And finally turn it into some AdaptiveDataLoaders.

These are just fastai's DataLoaders class, but it overrides a few functions to have it work nicely with HuggingFace's Dataset class

LanguageModelDatasets.dataloaders[source]

LanguageModelDatasets.dataloaders(batch_size=8, shuffle_train=True, collate_fn=default_data_collator, mlm_probability:float=0.15, path='.', device=None)

Build DataLoaders from self

Parameters:

  • batch_size : <class 'int'>, optional

    A batch size

  • shuffle_train : <class 'bool'>, optional

    Whether to shuffle the training dataset

  • collate_fn : <class 'function'>, optional

    A custom collation function

  • mlm_probability : <class 'float'>, optional

    Token masking probablity for Masked Language Models

  • path : <class 'str'>, optional

  • device : <class 'NoneType'>, optional

dls = dsets.dataloaders(batch_size=8)

Finally, let's view a batch of data with the show_batch function:

dls.show_batch()
Input Label
0 lighter or darker narrative and theme in his film.....Alain Delon visits swift, sure vengeance on the ruthless crime family that employed him as a hit-man in the Duccio Tessari thriller "Big Guns" after they accidentally murder his wife and child. Tessari and scenarists Roberto Gandus, Ugo Liberatore of "A Minute to Pray, a Second to Die," and Franco Verucci of "Ring of Death" take this actioneer about a career gunman for the mob right down to the wire. Indeed, "Big Guns" is rather predictable, but it still qualifies as solid entertainment with lots of savage and often sudden killings. Alain Delon of "The Godson" is appropriately laconic as he methodically deals out death to the heads of the mob families who refused to let him retire so that he could enjoy life with his young son and daughter. Richard Conte of "The Godfather" plays a Sicilian crime boss who wants to bury the hatchet with the Delon character, but the rest of his hard-nosed associates want the hit-man dead. Like most crime thrillers in the 1960s and 1970s, "Big Guns" subscribes to the cinematic morality that crime does not pay. Interestingly, the one man who has nothing to do with the murder of the wife and son of the hero survives while another betrays the hero with extreme prejudice. Tessari does not waste a second in this 90-minute shoot'em up. Apart from the mother and son dying in a car bomb meant for the father, the worst thing that takes place occurs in an automobile salvage yard when an associate of the hero is crushed in a junked car. Ostensibly, "Big Guns" is a rather bloodless outing, but it does have a high body count for a 1973 mobster melodrama. Only at the last minute does our protagonist let his guard down and so the contrived morality of an eye for an eye remains intact. Tessari stages a couple of decent car chases and the death of a don in a train traveling through a train tunnel is as bloody as this violent yarn gets. The photography and the compositions are excellent.This very funny British comedy shows what might happen if a section of London, in this case Pimlico, were to declare itself independent from the rest of the UK and its laws, taxes & post-war restrictions. Merry mayhem is what would happen.<br /><br />The explosion of a wartime bomb leads to the lighter or darker narrative and theme in his film.....Alain Delon visits swift, sure vengeance on the ruthless crime family that employed him as a hit-man in the Duccio Tessari thriller "Big Guns" after they accidentally murder his wife and child. Tessari and scenarists Roberto Gandus, Ugo Liberatore of "A Minute to Pray, a Second to Die," and Franco Verucci of "Ring of Death" take this actioneer about a career gunman for the mob right down to the wire. Indeed, "Big Guns" is rather predictable, but it still qualifies as solid entertainment with lots of savage and often sudden killings. Alain Delon of "The Godson" is appropriately laconic as he methodically deals out death to the heads of the mob families who refused to let him retire so that he could enjoy life with his young son and daughter. Richard Conte of "The Godfather" plays a Sicilian crime boss who wants to bury the hatchet with the Delon character, but the rest of his hard-nosed associates want the hit-man dead. Like most crime thrillers in the 1960s and 1970s, "Big Guns" subscribes to the cinematic morality that crime does not pay. Interestingly, the one man who has nothing to do with the murder of the wife and son of the hero survives while another betrays the hero with extreme prejudice. Tessari does not waste a second in this 90-minute shoot'em up. Apart from the mother and son dying in a car bomb meant for the father, the worst thing that takes place occurs in an automobile salvage yard when an associate of the hero is crushed in a junked car. Ostensibly, "Big Guns" is a rather bloodless outing, but it does have a high body count for a 1973 mobster melodrama. Only at the last minute does our protagonist let his guard down and so the contrived morality of an eye for an eye remains intact. Tessari stages a couple of decent car chases and the death of a don in a train traveling through a train tunnel is as bloody as this violent yarn gets. The photography and the compositions are excellent.This very funny British comedy shows what might happen if a section of London, in this case Pimlico, were to declare itself independent from the rest of the UK and its laws, taxes & post-war restrictions. Merry mayhem is what would happen.<br /><br />The explosion of a wartime bomb leads to the
1 éus. Beautiful Frida Hallgren is enchanting with her pretty smile and her subtle acting. The choir members are all well-developed, interesting characters with their own story each.<br /><br />This movie tells a story, a beautiful story, about music, love, pain, memories, death, about a man who devoted his life to music, and who tries to create a calm existence in the village where he was born, while trying to make peace with the past and with the way his life has been till then. Kay Pollack shows us that the Swedish are outstanding movie creators. Go see Så som i himmelen, it's a movie that makes you think about life and love, and that's also comforting, in some way.The spoiler warning is for those people who want to see for themselves what animals and landscapes pass before their eyes, although I don't mention it in great detail.<br /><br />"Earth" is an approx. 90 minute cinema version based on "Planet earth" which I watched all on BBC TV.The TV version was narrated by David Attenborough, a captivating commentator, who I had wished had also done it for "Earth" but it is Patrick Stewart, Star Trek's Captain Picard. There are regularly shots of the Earth from space so that's may be appropriate. In any case he has a nice enough and calm voice for it. There are 12 chapters in which we follow animal life on earth from North Pole to Antarctica. 3 animal families, polar bear, elephant and whale, appear in more than one of these parts. Each "chapter" starts with an indication how far from north pole or equator it is. We see something of each kind of animal, but only mammals and birds, and some fish, and some beautiful shots of vegetation, mountains, waterfalls, deserts and jungle, a near perfect presentation of the variety of life and landscapes and climates on earth. You get the impression that our planet is only inhabited by animals: people or villages or cities aren't in the film, so it's a typical nature documentary, but breathtakingly shot and accompanied by delightful music. When the film opened I already knew it would end far too soon for me. It is a family film, so no brutal killings of any animals. When one is caught by his hunter the shot ends and in other cases where we see the prey being caught it's shot in slow-motion which makes it less violent and watchable for young children (age limit 6 in The Netherlands éus. Beautiful Frida Hallgren is enchanting with her pretty smile and her subtle acting. The choir members are all well-developed, interesting characters with their own story each.<br /><br />This movie tells a story, a beautiful story, about music, love, pain, memories, death, about a man who devoted his life to music, and who tries to create a calm existence in the village where he was born, while trying to make peace with the past and with the way his life has been till then. Kay Pollack shows us that the Swedish are outstanding movie creators. Go see Så som i himmelen, it's a movie that makes you think about life and love, and that's also comforting, in some way.The spoiler warning is for those people who want to see for themselves what animals and landscapes pass before their eyes, although I don't mention it in great detail.<br /><br />"Earth" is an approx. 90 minute cinema version based on "Planet earth" which I watched all on BBC TV.The TV version was narrated by David Attenborough, a captivating commentator, who I had wished had also done it for "Earth" but it is Patrick Stewart, Star Trek's Captain Picard. There are regularly shots of the Earth from space so that's may be appropriate. In any case he has a nice enough and calm voice for it. There are 12 chapters in which we follow animal life on earth from North Pole to Antarctica. 3 animal families, polar bear, elephant and whale, appear in more than one of these parts. Each "chapter" starts with an indication how far from north pole or equator it is. We see something of each kind of animal, but only mammals and birds, and some fish, and some beautiful shots of vegetation, mountains, waterfalls, deserts and jungle, a near perfect presentation of the variety of life and landscapes and climates on earth. You get the impression that our planet is only inhabited by animals: people or villages or cities aren't in the film, so it's a typical nature documentary, but breathtakingly shot and accompanied by delightful music. When the film opened I already knew it would end far too soon for me. It is a family film, so no brutal killings of any animals. When one is caught by his hunter the shot ends and in other cases where we see the prey being caught it's shot in slow-motion which makes it less violent and watchable for young children (age limit 6 in The Netherlands
2 the entire film. <br /><br />Why would a company release a DVD that the cover is so misleading? I feel like such an idiot for renting this movie based strictly on the box. As much as I explore IMDb I should have done a little research and made a list prior to visiting my local video rental store. I have no one to blame except myself. I want my money and time back. <br /><br />DO NOT WATCH THIS MOVIE. <br /><br />Even if curiosity is motivating you, stick cocktail umbrellas in your eyes instead. It will be much more enjoyable. You have been warned!I love this film. It is well written and acted and has good cinematography. The story blends action, humor, mysticism, and tenderness with great sets and beautiful location shots. See it, buy it, show it to your friends.<br /><br />The acting is good and Murphy especially does a fine job portraying the reluctant/unlikely hero. I enjoyed all the characters and found them to be interesting and well developed with dynamic interactions.<br /><br />I cared what happened to these people and, while the outcome was pretty predictable (the good guys win, the hero gets the astonishingly attractive girl and the holy child saves lives--who doesn't see that coming?), it still made me happy when everything worked out well in the end. Thank God this film's dignity was never ruined with a crappy sequel. Grab some popcorn, cuddle up on the couch, and watch this fun, happy and entertaining film.While I count myself as a fan of the Babylon 5 television series, the original movie that introduced the series was a weak start. Although many of the elements that would later mature and become much more compelling in the series are there, the pace of The Gathering is slow, the makeup somewhat inadequate, and the plot confusing. Worse, the characterization in the premiere episode is poor. Although the ratings chart shows that many fans are willing to overlook these problems, I remember The Gathering almost turned me off off what soon grew into a spectacular series.What the *bliep* is it with this movie? Couldn't they fiend a better script? All in all a 'nice' movie, but... it has been done more than once... Up till the end I thought it was okay, but... the going back to the past part... *barf* SO corny... Was waiting for the fairy god mother to appear... but wow, that the entire film. <br /><br />Why would a company release a DVD that the cover is so misleading? I feel like such an idiot for renting this movie based strictly on the box. As much as I explore IMDb I should have done a little research and made a list prior to visiting my local video rental store. I have no one to blame except myself. I want my money and time back. <br /><br />DO NOT WATCH THIS MOVIE. <br /><br />Even if curiosity is motivating you, stick cocktail umbrellas in your eyes instead. It will be much more enjoyable. You have been warned!I love this film. It is well written and acted and has good cinematography. The story blends action, humor, mysticism, and tenderness with great sets and beautiful location shots. See it, buy it, show it to your friends.<br /><br />The acting is good and Murphy especially does a fine job portraying the reluctant/unlikely hero. I enjoyed all the characters and found them to be interesting and well developed with dynamic interactions.<br /><br />I cared what happened to these people and, while the outcome was pretty predictable (the good guys win, the hero gets the astonishingly attractive girl and the holy child saves lives--who doesn't see that coming?), it still made me happy when everything worked out well in the end. Thank God this film's dignity was never ruined with a crappy sequel. Grab some popcorn, cuddle up on the couch, and watch this fun, happy and entertaining film.While I count myself as a fan of the Babylon 5 television series, the original movie that introduced the series was a weak start. Although many of the elements that would later mature and become much more compelling in the series are there, the pace of The Gathering is slow, the makeup somewhat inadequate, and the plot confusing. Worse, the characterization in the premiere episode is poor. Although the ratings chart shows that many fans are willing to overlook these problems, I remember The Gathering almost turned me off off what soon grew into a spectacular series.What the *bliep* is it with this movie? Couldn't they fiend a better script? All in all a 'nice' movie, but... it has been done more than once... Up till the end I thought it was okay, but... the going back to the past part... *barf* SO corny... Was waiting for the fairy god mother to appear... but wow, that
3 John Thaw is mesmerising as Tom Oakley. His transformation from gruff to caring was so well realised, making it more believable than Scrooge in Christmas Carol. After Inspector Morse, this is Thaw's finest hour. He was matched earnestly by a young Nick Robinson, who gave a thoroughly convincing portrayal of an evacuee traumatised by the abusive relationship with his mother. The script and music made it worth the buy, and you also see Thaw playing the organ. Amazing! The most moving scene, was Willie finding out about Zak's death, and then Tom telling him about his deceased family who died of scarlatina. Buy this, you'll love it! 10/10 Bethany CoxI had read many good things about this adaptation of my favorite novel...so invariably my expectations were crushed. But they were crushed more than should be expected. The movie would have been a decent movie if I had not read the novel beforehand, which perhaps ruined it for me.<br /><br />In any event, for some reason they changed the labor camp at Toulon to a ship full of galley slaves. The scene at Bishop Myriel's was fine. In fact, other than the galleys, things survived up until the dismissal of Fantine. Because we do not want to have bad things happen to a good woman, she does not cut her hair, sell her teeth, or become a prostitute. The worst she does is run into the mayor's office and spit on his face. Bamatabois is entirely eliminated. Because having children out of wedlock should also not be talked about, Tholomyes is Fantine's dead husband, rather than an irresponsible dandy. Valjean is able to fetch Cosette for Fantine before the Champmathieu affair, so they reunite happily, yet another change. Then comes the convent, which is a pretty difficult scene to screw up. Thankfully, it was saved. After this three minutes of accuracy, however, the movie again begins to hurtle towards Classic Novel Butchering.<br /><br />As Cosette and Valjean are riding through the park, they come across Marius giving a speech at a meeting. About prison reform. When he comes to hand out fliers to Valjean and Cosette, he says the one line in the movie that set me screaming at the TV set. "We aren't revolutionaries." I could hear Victor Hugo thrashing in his grave. OF COURSE THEY ARE REVOL John Thaw is mesmerising as Tom Oakley. His transformation from gruff to caring was so well realised, making it more believable than Scrooge in Christmas Carol. After Inspector Morse, this is Thaw's finest hour. He was matched earnestly by a young Nick Robinson, who gave a thoroughly convincing portrayal of an evacuee traumatised by the abusive relationship with his mother. The script and music made it worth the buy, and you also see Thaw playing the organ. Amazing! The most moving scene, was Willie finding out about Zak's death, and then Tom telling him about his deceased family who died of scarlatina. Buy this, you'll love it! 10/10 Bethany CoxI had read many good things about this adaptation of my favorite novel...so invariably my expectations were crushed. But they were crushed more than should be expected. The movie would have been a decent movie if I had not read the novel beforehand, which perhaps ruined it for me.<br /><br />In any event, for some reason they changed the labor camp at Toulon to a ship full of galley slaves. The scene at Bishop Myriel's was fine. In fact, other than the galleys, things survived up until the dismissal of Fantine. Because we do not want to have bad things happen to a good woman, she does not cut her hair, sell her teeth, or become a prostitute. The worst she does is run into the mayor's office and spit on his face. Bamatabois is entirely eliminated. Because having children out of wedlock should also not be talked about, Tholomyes is Fantine's dead husband, rather than an irresponsible dandy. Valjean is able to fetch Cosette for Fantine before the Champmathieu affair, so they reunite happily, yet another change. Then comes the convent, which is a pretty difficult scene to screw up. Thankfully, it was saved. After this three minutes of accuracy, however, the movie again begins to hurtle towards Classic Novel Butchering.<br /><br />As Cosette and Valjean are riding through the park, they come across Marius giving a speech at a meeting. About prison reform. When he comes to hand out fliers to Valjean and Cosette, he says the one line in the movie that set me screaming at the TV set. "We aren't revolutionaries." I could hear Victor Hugo thrashing in his grave. OF COURSE THEY ARE REVOL
4 first human attempt with both eyes at the same time, that's totally unprofessional. And to do all this apparently without informed consent of the patient?! And why on earth choose for eyes that have a totally unusual color for humans, and make the victim look like a freak?! By the way, I noticed that all the real wolves in the movie had puppy-like normal dark eyes, couldn't they have waited for such a specimen? The story is lame, it's about this poor guy Aaron who gets these weird eye-transplants, which suddenly makes him feel like the donor-wolf (or at least, that's what I make of it) and then he's being chased by some military men. Especially this last bit is ridiculous. I mean, I can understand that the army is interested in the results of the experiment (imagine soldiers with night-vision eye-sight!) but as the operation fails on account of the apparent nervous breakdown of the patient, it's beyond me why they're out to kill him. Why not leave him alone and look for another usable recipient? (a volunteering soldier maybe??). And why try to kill everyone else that's involved with poor Aaron, isn't that a bit steep?! Who the hell are these militaries anyway, I hope not the US army or the government, they behave like psychopaths, walking around the hospital waving automatic weapons, raiding private apartments like they're after some public enemy # 1, and displaying during the ultimate show-down in the woods a total lack of discipline, like a bunch of frightened schoolchildren, panicking and shooting randomly around.<br /><br />Aaron, for some unfathomable medical reason, feels like a wolf after the transplantation of the eyes. Why would that be??? He suddenly sees visions of wandering wolves. What is this? Are we supposed to believe that the memories of the donor-wolf are situated in it's eye-balls?!? And that the recipient of these eye-balls also adopts the wolf's craving for red (life-) meat and can jump off of a 30 feet high balcony and land unharmed on his all-fours like a cat (can a wolf even DO that??!).<br /><br />The acting (or the lack thereof) didn't help the credibility of all this either: everyone stumbles through their lines like wooden dolls, especially this Indian girl, she may be pretty but she can only come up with one expression (vexed) and some disinterested mumblings about first human attempt with both eyes at the same time, that's totally unprofessional. And to do all this apparently without informed consent of the patient?! And why on earth choose for eyes that have a totally unusual color for humans, and make the victim look like a freak?! By the way, I noticed that all the real wolves in the movie had puppy-like normal dark eyes, couldn't they have waited for such a specimen? The story is lame, it's about this poor guy Aaron who gets these weird eye-transplants, which suddenly makes him feel like the donor-wolf (or at least, that's what I make of it) and then he's being chased by some military men. Especially this last bit is ridiculous. I mean, I can understand that the army is interested in the results of the experiment (imagine soldiers with night-vision eye-sight!) but as the operation fails on account of the apparent nervous breakdown of the patient, it's beyond me why they're out to kill him. Why not leave him alone and look for another usable recipient? (a volunteering soldier maybe??). And why try to kill everyone else that's involved with poor Aaron, isn't that a bit steep?! Who the hell are these militaries anyway, I hope not the US army or the government, they behave like psychopaths, walking around the hospital waving automatic weapons, raiding private apartments like they're after some public enemy # 1, and displaying during the ultimate show-down in the woods a total lack of discipline, like a bunch of frightened schoolchildren, panicking and shooting randomly around.<br /><br />Aaron, for some unfathomable medical reason, feels like a wolf after the transplantation of the eyes. Why would that be??? He suddenly sees visions of wandering wolves. What is this? Are we supposed to believe that the memories of the donor-wolf are situated in it's eye-balls?!? And that the recipient of these eye-balls also adopts the wolf's craving for red (life-) meat and can jump off of a 30 feet high balcony and land unharmed on his all-fours like a cat (can a wolf even DO that??!).<br /><br />The acting (or the lack thereof) didn't help the credibility of all this either: everyone stumbles through their lines like wooden dolls, especially this Indian girl, she may be pretty but she can only come up with one expression (vexed) and some disinterested mumblings about

When training a language model, the input and output are made to be the exact same, so there isn't a shown noticable difference here.

Building Tuner

Next we need to build a compatible Tuner for our problem. These tuners contain good defaults for our problem space, including loss functions and metrics.

First let's import the LanguageModelTuner and view it's documentation

from adaptnlp import LanguageModelTuner

class LanguageModelTuner[source]

LanguageModelTuner(dls:DataLoaders, model_name, tokenizer=None, language_model_type:LMType='causal', loss_func=CrossEntropyLoss(), metrics=[<fastai.metrics.Perplexity object at 0x7fe483364100>], opt_func=Adam, additional_cbs=None, expose_fastai_api=False, **kwargs) :: AdaptiveTuner

An AdaptiveTuner with good defaults for Language Model fine-tuning Valid kwargs and defaults:

  • lr:float = 0.001
  • splitter:function = trainable_params
  • cbs:list = None
  • path:Path = None
  • model_dir:Path = 'models'
  • wd:float = None
  • wd_bn_bias:bool = False
  • train_bn:bool = True
  • moms: tuple(float) = (0.95, 0.85, 0.95)

Parameters:

  • dls : <class 'fastai.data.core.DataLoaders'>

    A set of DataLoaders or AdaptiveDataLoaders

  • model_name : <class 'inspect._empty'>

    A HuggingFace model

  • tokenizer : <class 'NoneType'>, optional

    A HuggingFace tokenizer

  • language_model_type : <class 'fastcore.basics.LMType'>, optional

    The type of language model to use

  • loss_func : <class 'fastai.losses.CrossEntropyLossFlat'>, optional

    A loss function

  • metrics : <class 'list'>, optional

    Metrics to monitor the training with

  • opt_func : <class 'function'>, optional

    A fastai or torch Optimizer

  • additional_cbs : <class 'NoneType'>, optional

    Additional Callbacks to have always tied to the Tuner,

  • expose_fastai_api : <class 'bool'>, optional

    Whether to expose the fastai API

  • kwargs : <class 'inspect._empty'>

Next we'll pass in our DataLoaders, the name of our model, and the tokenizer:

tuner = LanguageModelTuner(dls, model.name, dls.tokenizer)

By default we can see that it used CrossEntropyLoss as our loss function, and Perplexity as our metric

tuner.loss_func
FlattenedLoss of CrossEntropyLoss()
_ = [print(m.name) for m in tuner.metrics]
perplexity

Finally we just need to train our model!

Fine-Tuning

To fine-tune, AdaptNLP's tuner class provides only a few functions to work with. The important ones are the tune and lr_find class.

As the Tuner uses fastai under the hood, lr_find calls fastai's Learning Rate Finder to help us pick a learning rate. Let's do that now:

AdaptiveTuner.lr_find[source]

AdaptiveTuner.lr_find(start_lr=1e-07, end_lr=10, num_it=100, stop_div=True, show_plot=True, suggest_funcs=valley)

Runs fastai's LR Finder

Parameters:

  • start_lr : <class 'float'>, optional

  • end_lr : <class 'int'>, optional

  • num_it : <class 'int'>, optional

  • stop_div : <class 'bool'>, optional

  • show_plot : <class 'bool'>, optional

  • suggest_funcs : <class 'function'>, optional

tuner.lr_find()
/opt/venv/lib/python3.8/site-packages/fastai/callback/schedule.py:270: UserWarning: color is redundantly defined by the 'color' keyword argument and the fmt string "ro" (-> color='r'). The keyword argument will take precedence.
  ax.plot(val, idx, 'ro', label=nm, c=color)
SuggestedLRs(valley=7.585775892948732e-05)

It recommends a learning rate of around 5e-5, so we will use that.

lr = 5e-5

Let's look at the documentation for tune:

AdaptiveTuner.tune[source]

AdaptiveTuner.tune(epochs:int, lr:float=None, strategy:Strategy='fit_one_cycle', callbacks:list=[], **kwargs)

Fine tune self.model for epochs with an lr and strategy

Parameters:

  • epochs : <class 'int'>

    Number of iterations to train for

  • lr : <class 'float'>, optional

    If None, finds a new learning rate and uses suggestion_method

  • strategy : <class 'fastcore.basics.Strategy'>, optional

    A fitting method

  • callbacks : <class 'list'>, optional

    Extra fastai Callbacks

  • kwargs : <class 'inspect._empty'>

We can pass in a number of epochs, a learning rate, a strategy, and additional fastai callbacks to call.

Valid strategies live in the Strategy namespace class, and consist of:

from adaptnlp import Strategy

In this tutorial we will train with the One-Cycle policy, as currently it is one of the best schedulers to use.

tuner.tune(3, lr, strategy=Strategy.OneCycle)

Saving Model

Now that we have a trained model, let's save those weights away.

Calling tuner.save will save both the model and the tokenizer in the same format as how HuggingFace does:

AdaptiveTuner.save[source]

AdaptiveTuner.save(save_directory)

Save a pretrained model to a save_directory

Parameters:

  • save_directory : <class 'inspect._empty'>

    A folder to save our model to

tuner.save('good_model')
'good_model'

Performing Inference

There are two ways to get predictions, the first is with the .predict method in our tuner. This is great for if you just finished training and want to see how your model performs on some new data! The other method is with AdaptNLP's inference API, which we will show afterwards

In Tuner

First let's write a sentence to test with

sentence = "Hugh Jackman is a terrible "

And then predict with it:

LanguageModelTuner.predict[source]

LanguageModelTuner.predict(text:Union[List[str], str], bs:int=64, num_tokens_to_produce:int=50, **kwargs)

Predict some text for sequence classification with the currently loaded model

Parameters:

  • text : typing.Union[typing.List[str], str]

    Some text or list of texts to do inference with

  • bs : <class 'int'>, optional

    A batch size to use for multiple texts

  • num_tokens_to_produce : <class 'int'>, optional

    Number of tokens to generate

  • kwargs : <class 'inspect._empty'>
tuner.predict(sentence, num_tokens_to_produce=8)
100.00% [1/1 00:00<00:00]
{'generated_text': ['Hugh Jackman is a terrible icky, and very funny, character.']}

With the Inference API

Next we will use the EasyTextGenerator class, which AdaptNLP offers:

from adaptnlp import EasyTextGenerator

We simply construct the class:

classifier = EasyTextGenerator()

And call the tag_text method, passing in the sentence, the location of our saved model, and some names for our classes:

classifier.generate(
    sentence,
    model_name_or_path='good_model',
    num_tokens_to_produce=8
)
100.00% [1/1 00:00<00:00]
{'generated_text': ['Hugh Jackman is a terrible icky, and very funny, character.']}

And we got the exact same output!