import{S as dd,i as ud,s as fd,e as o,w as j,k as c,t as a,c as r,a as i,x as E,d as s,m as h,h as l,b as k,g as p,G as t,y as x,q as b,o as w,B as O,M as md,N as sc,p as So,v as _d,n as Fo,L as rd}from"../../chunks/vendor-hf-doc-builder.js";import{T as Lo}from"../../chunks/Tip-hf-doc-builder.js";import{Y as id}from"../../chunks/Youtube-hf-doc-builder.js";import{I as Ct}from"../../chunks/IconCopyLink-hf-doc-builder.js";import{C as q}from"../../chunks/CodeBlock-hf-doc-builder.js";import{C as hd}from"../../chunks/CourseFloatingBanner-hf-doc-builder.js";import{F as bd}from"../../chunks/FrameworkSwitchCourse-hf-doc-builder.js";function wd(U){let d,g;return d=new hd({props:{chapter:7,classNames:"absolute z-10 right-0 top-0",notebooks:[{label:"Google Colab",value:"https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/en/chapter7/section2_tf.ipynb"},{label:"Aws Studio",value:"https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/en/chapter7/section2_tf.ipynb"}]}}),{c(){j(d.$$.fragment)},l(m){E(d.$$.fragment,m)},m(m,$){x(d,m,$),g=!0},i(m){g||(b(d.$$.fragment,m),g=!0)},o(m){w(d.$$.fragment,m),g=!1},d(m){O(d,m)}}}function gd(U){let d,g;return d=new hd({props:{chapter:7,classNames:"absolute z-10 right-0 top-0",notebooks:[{label:"Google Colab",value:"https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/en/chapter7/section2_pt.ipynb"},{label:"Aws Studio",value:"https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/en/chapter7/section2_pt.ipynb"}]}}),{c(){j(d.$$.fragment)},l(m){E(d.$$.fragment,m)},m(m,$){x(d,m,$),g=!0},i(m){g||(b(d.$$.fragment,m),g=!0)},o(m){w(d.$$.fragment,m),g=!1},d(m){O(d,m)}}}function vd(U){let d,g,m,$,T,v,y,D;return{c(){d=o("p"),g=a("\u{1F4A1} As long as your dataset consists of texts split into words with their corresponding labels, you will be able to adapt the data processing procedures described here to your own dataset. Refer back to "),m=o("a"),$=a("Chapter 5"),T=a(" if you need a refresher on how to load your own custom data in a "),v=o("code"),y=a("Dataset"),D=a("."),this.h()},l(z){d=r(z,"P",{});var N=i(d);g=l(N,"\u{1F4A1} As long as your dataset consists of texts split into words with their corresponding labels, you will be able to adapt the data processing procedures described here to your own dataset. Refer back to "),m=r(N,"A",{href:!0});var B=i(m);$=l(B,"Chapter 5"),B.forEach(s),T=l(N," if you need a refresher on how to load your own custom data in a "),v=r(N,"CODE",{});var A=i(v);y=l(A,"Dataset"),A.forEach(s),D=l(N,"."),N.forEach(s),this.h()},h(){k(m,"href","/course/chapter5")},m(z,N){p(z,d,N),t(d,g),t(d,m),t(m,$),t(d,T),t(d,v),t(v,y),t(d,D)},d(z){z&&s(d)}}}function kd(U){let d,g,m,$,T;return{c(){d=o("p"),g=a("\u270F\uFE0F "),m=o("strong"),$=a("Your turn!"),T=a(" Print the same two sentences with their POS or chunking labels.")},l(v){d=r(v,"P",{});var y=i(d);g=l(y,"\u270F\uFE0F "),m=r(y,"STRONG",{});var D=i(m);$=l(D,"Your turn!"),D.forEach(s),T=l(y," Print the same two sentences with their POS or chunking labels."),y.forEach(s)},m(v,y){p(v,d,y),t(d,g),t(d,m),t(m,$),t(d,T)},d(v){v&&s(d)}}}function $d(U){let d,g,m,$,T,v,y,D;return{c(){d=o("p"),g=a("\u270F\uFE0F "),m=o("strong"),$=a("Your turn!"),T=a(" Some researchers prefer to attribute only one label per word, and assign "),v=o("code"),y=a("-100"),D=a(" to the other subtokens in a given word. This is to avoid long words that split into lots of subtokens contributing heavily to the loss. Change the previous function to align labels with input IDs by following this rule.")},l(z){d=r(z,"P",{});var N=i(d);g=l(N,"\u270F\uFE0F "),m=r(N,"STRONG",{});var B=i(m);$=l(B,"Your turn!"),B.forEach(s),T=l(N," Some researchers prefer to attribute only one label per word, and assign "),v=r(N,"CODE",{});var A=i(v);y=l(A,"-100"),A.forEach(s),D=l(N," to the other subtokens in a given word. This is to avoid long words that split into lots of subtokens contributing heavily to the loss. Change the previous function to align labels with input IDs by following this rule."),N.forEach(s)},m(z,N){p(z,d,N),t(d,g),t(d,m),t(m,$),t(d,T),t(d,v),t(v,y),t(d,D)},d(z){z&&s(d)}}}function yd(U){let d,g,m,$,T,v,y,D,z,N,B;return $=new Ct({}),{c(){d=o("h2"),g=o("a"),m=o("span"),j($.$$.fragment),T=c(),v=o("span"),y=a("Fine-tuning the model with Keras"),D=c(),z=o("p"),N=a("The actual code using Keras will be very similar to before; the only changes are the way the data is collated into a batch and the metric computation function."),this.h()},l(A){d=r(A,"H2",{class:!0});var I=i(d);g=r(I,"A",{id:!0,class:!0,href:!0});var M=i(g);m=r(M,"SPAN",{});var G=i(m);E($.$$.fragment,G),G.forEach(s),M.forEach(s),T=h(I),v=r(I,"SPAN",{});var Z=i(v);y=l(Z,"Fine-tuning the model with Keras"),Z.forEach(s),I.forEach(s),D=h(A),z=r(A,"P",{});var X=i(z);N=l(X,"The actual code using Keras will be very similar to before; the only changes are the way the data is collated into a batch and the metric computation function."),X.forEach(s),this.h()},h(){k(g,"id","finetuning-the-model-with-keras"),k(g,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(g,"href","#finetuning-the-model-with-keras"),k(d,"class","relative group")},m(A,I){p(A,d,I),t(d,g),t(g,m),x($,m,null),t(d,T),t(d,v),t(v,y),p(A,D,I),p(A,z,I),t(z,N),B=!0},i(A){B||(b($.$$.fragment,A),B=!0)},o(A){w($.$$.fragment,A),B=!1},d(A){A&&s(d),O($),A&&s(D),A&&s(z)}}}function jd(U){let d,g,m,$,T,v,y,D,z,N,B,A,I,M,G,Z,X;return $=new Ct({}),{c(){d=o("h2"),g=o("a"),m=o("span"),j($.$$.fragment),T=c(),v=o("span"),y=a("Fine-tuning the model with the "),D=o("code"),z=a("Trainer"),N=a(" API"),B=c(),A=o("p"),I=a("The actual code using the "),M=o("code"),G=a("Trainer"),Z=a(" will be the same as before; the only changes are the way the data is collated into a batch and the metric computation function."),this.h()},l(C){d=r(C,"H2",{class:!0});var S=i(d);g=r(S,"A",{id:!0,class:!0,href:!0});var P=i(g);m=r(P,"SPAN",{});var H=i(m);E($.$$.fragment,H),H.forEach(s),P.forEach(s),T=h(S),v=r(S,"SPAN",{});var F=i(v);y=l(F,"Fine-tuning the model with the "),D=r(F,"CODE",{});var Y=i(D);z=l(Y,"Trainer"),Y.forEach(s),N=l(F," API"),F.forEach(s),S.forEach(s),B=h(C),A=r(C,"P",{});var Q=i(A);I=l(Q,"The actual code using the "),M=r(Q,"CODE",{});var ee=i(M);G=l(ee,"Trainer"),ee.forEach(s),Z=l(Q," will be the same as before; the only changes are the way the data is collated into a batch and the metric computation function."),Q.forEach(s),this.h()},h(){k(g,"id","finetuning-the-model-with-the-trainer-api"),k(g,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(g,"href","#finetuning-the-model-with-the-trainer-api"),k(d,"class","relative group")},m(C,S){p(C,d,S),t(d,g),t(g,m),x($,m,null),t(d,T),t(d,v),t(v,y),t(v,D),t(D,z),t(v,N),p(C,B,S),p(C,A,S),t(A,I),t(A,M),t(M,G),t(A,Z),X=!0},i(C){X||(b($.$$.fragment,C),X=!0)},o(C){w($.$$.fragment,C),X=!1},d(C){C&&s(d),O($),C&&s(B),C&&s(A)}}}function Ed(U){let d,g;return d=new q({props:{code:`from transformers import DataCollatorForTokenClassification

data_collator = DataCollatorForTokenClassification(
    tokenizer=tokenizer, return_tensors="tf"
)`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> DataCollatorForTokenClassification

data_collator = DataCollatorForTokenClassification(
    tokenizer=tokenizer, return_tensors=<span class="hljs-string">&quot;tf&quot;</span>
)`}}),{c(){j(d.$$.fragment)},l(m){E(d.$$.fragment,m)},m(m,$){x(d,m,$),g=!0},i(m){g||(b(d.$$.fragment,m),g=!0)},o(m){w(d.$$.fragment,m),g=!1},d(m){O(d,m)}}}function xd(U){let d,g;return d=new q({props:{code:`from transformers import DataCollatorForTokenClassification

data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer)`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> DataCollatorForTokenClassification

data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer)`}}),{c(){j(d.$$.fragment)},l(m){E(d.$$.fragment,m)},m(m,$){x(d,m,$),g=!0},i(m){g||(b(d.$$.fragment,m),g=!0)},o(m){w(d.$$.fragment,m),g=!1},d(m){O(d,m)}}}function Od(U){let d,g,m,$,T,v,y,D,z,N,B,A,I,M,G,Z,X;return I=new q({props:{code:`tf_train_dataset = tokenized_datasets["train"].to_tf_dataset(
    columns=["attention_mask", "input_ids", "labels", "token_type_ids"],
    collate_fn=data_collator,
    shuffle=True,
    batch_size=16,
)

tf_eval_dataset = tokenized_datasets["validation"].to_tf_dataset(
    columns=["attention_mask", "input_ids", "labels", "token_type_ids"],
    collate_fn=data_collator,
    shuffle=False,
    batch_size=16,
)`,highlighted:`tf_train_dataset = tokenized_datasets[<span class="hljs-string">&quot;train&quot;</span>].to_tf_dataset(
    columns=[<span class="hljs-string">&quot;attention_mask&quot;</span>, <span class="hljs-string">&quot;input_ids&quot;</span>, <span class="hljs-string">&quot;labels&quot;</span>, <span class="hljs-string">&quot;token_type_ids&quot;</span>],
    collate_fn=data_collator,
    shuffle=<span class="hljs-literal">True</span>,
    batch_size=<span class="hljs-number">16</span>,
)

tf_eval_dataset = tokenized_datasets[<span class="hljs-string">&quot;validation&quot;</span>].to_tf_dataset(
    columns=[<span class="hljs-string">&quot;attention_mask&quot;</span>, <span class="hljs-string">&quot;input_ids&quot;</span>, <span class="hljs-string">&quot;labels&quot;</span>, <span class="hljs-string">&quot;token_type_ids&quot;</span>],
    collate_fn=data_collator,
    shuffle=<span class="hljs-literal">False</span>,
    batch_size=<span class="hljs-number">16</span>,
)`}}),{c(){d=o("p"),g=a("Our data collator is ready to go! Now let\u2019s use it to make a "),m=o("code"),$=a("tf.data.Dataset"),T=a(" with the "),v=o("code"),y=a("to_tf_dataset()"),D=a(" method. You can also use "),z=o("code"),N=a("model.prepare_tf_dataset()"),B=a(" to do this with a bit less boilerplate code - you\u2019ll see this in some of the other sections of this chapter."),A=c(),j(I.$$.fragment),M=c(),G=o("p"),Z=a("Next stop: the model itself.")},l(C){d=r(C,"P",{});var S=i(d);g=l(S,"Our data collator is ready to go! Now let\u2019s use it to make a "),m=r(S,"CODE",{});var P=i(m);$=l(P,"tf.data.Dataset"),P.forEach(s),T=l(S," with the "),v=r(S,"CODE",{});var H=i(v);y=l(H,"to_tf_dataset()"),H.forEach(s),D=l(S," method. You can also use "),z=r(S,"CODE",{});var F=i(z);N=l(F,"model.prepare_tf_dataset()"),F.forEach(s),B=l(S," to do this with a bit less boilerplate code - you\u2019ll see this in some of the other sections of this chapter."),S.forEach(s),A=h(C),E(I.$$.fragment,C),M=h(C),G=r(C,"P",{});var Y=i(G);Z=l(Y,"Next stop: the model itself."),Y.forEach(s)},m(C,S){p(C,d,S),t(d,g),t(d,m),t(m,$),t(d,T),t(d,v),t(v,y),t(d,D),t(d,z),t(z,N),t(d,B),p(C,A,S),x(I,C,S),p(C,M,S),p(C,G,S),t(G,Z),X=!0},i(C){X||(b(I.$$.fragment,C),X=!0)},o(C){w(I.$$.fragment,C),X=!1},d(C){C&&s(d),C&&s(A),O(I,C),C&&s(M),C&&s(G)}}}function Cd(U){let d,g,m,$,T;return{c(){d=o("p"),g=a("As we can see, the second set of labels has been padded to the length of the first one using "),m=o("code"),$=a("-100"),T=a("s.")},l(v){d=r(v,"P",{});var y=i(d);g=l(y,"As we can see, the second set of labels has been padded to the length of the first one using "),m=r(y,"CODE",{});var D=i(m);$=l(D,"-100"),D.forEach(s),T=l(y,"s."),y.forEach(s)},m(v,y){p(v,d,y),t(d,g),t(d,m),t(m,$),t(d,T)},i:rd,o:rd,d(v){v&&s(d)}}}function pd(U){let d,g,m,$,T,v,y,D,z,N,B,A,I,M,G,Z,X,C,S,P,H,F,Y,Q,ee,oe,K,de,J,W,R,le,ue,ye,ne,Fe,V,nt,pe,dt,Qt,ot,ea,Tt,es,we,Es,Te,fe,Ye,ts,se,ce,ss,Le,Dt,as,ta,Xe,Re,Pt,ls,zt,xs,je,De,qt,Ee,Da,At,Ze,Os,ie,It,Ke,ut,Pa,ft,mt,sa,Pe,ze,ns,te,Nt,_t,Ve,aa,qe,za,Cs,Je,Ts,la,bt,rt,Qe,Ds,os,Ps,na,wt,et,me,St,Ft,Ae,oa,_e,zs,qs,ra,rs,is,gt,vt,it,Lt,As,Ie,Rt,Bt,tt,ia,pt,Be,ct,Mt;return $=new Ct({}),K=new q({props:{code:`id2label = {i: label for i, label in enumerate(label_names)}
label2id = {v: k for k, v in id2label.items()}`,highlighted:`id2label = {i: label <span class="hljs-keyword">for</span> i, label <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(label_names)}
label2id = {v: k <span class="hljs-keyword">for</span> k, v <span class="hljs-keyword">in</span> id2label.items()}`}}),ne=new q({props:{code:`from transformers import TFAutoModelForTokenClassification

model = TFAutoModelForTokenClassification.from_pretrained(
    model_checkpoint,
    id2label=id2label,
    label2id=label2id,
)`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> TFAutoModelForTokenClassification

model = TFAutoModelForTokenClassification.from_pretrained(
    model_checkpoint,
    id2label=id2label,
    label2id=label2id,
)`}}),we=new q({props:{code:"model.config.num_labels",highlighted:"model.config.num_labels"}}),Te=new q({props:{code:"9",highlighted:'<span class="hljs-number">9</span>'}}),Ye=new Lo({props:{warning:!0,$$slots:{default:[Td]},$$scope:{ctx:U}}}),Le=new Ct({}),zt=new q({props:{code:`from huggingface_hub import notebook_login

notebook_login()`,highlighted:`<span class="hljs-keyword">from</span> huggingface_hub <span class="hljs-keyword">import</span> notebook_login

notebook_login()`}}),Ze=new q({props:{code:"huggingface-cli login",highlighted:"huggingface-cli login"}}),Nt=new q({props:{code:`from transformers import create_optimizer
import tensorflow as tf

# Train in mixed-precision float16
# Comment this line out if you're using a GPU that will not benefit from this
tf.keras.mixed_precision.set_global_policy("mixed_float16")

# The number of training steps is the number of samples in the dataset, divided by the batch size then multiplied
# by the total number of epochs. Note that the tf_train_dataset here is a batched tf.data.Dataset,
# not the original Hugging Face Dataset, so its len() is already num_samples // batch_size.
num_epochs = 3
num_train_steps = len(tf_train_dataset) * num_epochs

optimizer, schedule = create_optimizer(
    init_lr=2e-5,
    num_warmup_steps=0,
    num_train_steps=num_train_steps,
    weight_decay_rate=0.01,
)
model.compile(optimizer=optimizer)`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> create_optimizer
<span class="hljs-keyword">import</span> tensorflow <span class="hljs-keyword">as</span> tf

<span class="hljs-comment"># Train in mixed-precision float16</span>
<span class="hljs-comment"># Comment this line out if you&#x27;re using a GPU that will not benefit from this</span>
tf.keras.mixed_precision.set_global_policy(<span class="hljs-string">&quot;mixed_float16&quot;</span>)

<span class="hljs-comment"># The number of training steps is the number of samples in the dataset, divided by the batch size then multiplied</span>
<span class="hljs-comment"># by the total number of epochs. Note that the tf_train_dataset here is a batched tf.data.Dataset,</span>
<span class="hljs-comment"># not the original Hugging Face Dataset, so its len() is already num_samples // batch_size.</span>
num_epochs = <span class="hljs-number">3</span>
num_train_steps = <span class="hljs-built_in">len</span>(tf_train_dataset) * num_epochs

optimizer, schedule = create_optimizer(
    init_lr=<span class="hljs-number">2e-5</span>,
    num_warmup_steps=<span class="hljs-number">0</span>,
    num_train_steps=num_train_steps,
    weight_decay_rate=<span class="hljs-number">0.01</span>,
)
model.<span class="hljs-built_in">compile</span>(optimizer=optimizer)`}}),wt=new q({props:{code:`from transformers.keras_callbacks import PushToHubCallback

callback = PushToHubCallback(output_dir="bert-finetuned-ner", tokenizer=tokenizer)

model.fit(
    tf_train_dataset,
    validation_data=tf_eval_dataset,
    callbacks=[callback],
    epochs=num_epochs,
)`,highlighted:`<span class="hljs-keyword">from</span> transformers.keras_callbacks <span class="hljs-keyword">import</span> PushToHubCallback

callback = PushToHubCallback(output_dir=<span class="hljs-string">&quot;bert-finetuned-ner&quot;</span>, tokenizer=tokenizer)

model.fit(
    tf_train_dataset,
    validation_data=tf_eval_dataset,
    callbacks=[callback],
    epochs=num_epochs,
)`}}),Rt=new Lo({props:{$$slots:{default:[Dd]},$$scope:{ctx:U}}}),{c(){d=o("h3"),g=o("a"),m=o("span"),j($.$$.fragment),T=c(),v=o("span"),y=a("Defining the model"),D=c(),z=o("p"),N=a("Since we are working on a token classification problem, we will use the "),B=o("code"),A=a("TFAutoModelForTokenClassification"),I=a(" class. The main thing to remember when defining this model is to pass along some information on the number of labels we have. The easiest way to do this is to pass that number with the "),M=o("code"),G=a("num_labels"),Z=a(" argument, but if we want a nice inference widget working like the one we saw at the beginning of this section, it\u2019s better to set the correct label correspondences instead."),X=c(),C=o("p"),S=a("They should be set by two dictionaries, "),P=o("code"),H=a("id2label"),F=a(" and "),Y=o("code"),Q=a("label2id"),ee=a(", which contain the mapping from ID to label and vice versa:"),oe=c(),j(K.$$.fragment),de=c(),J=o("p"),W=a("Now we can just pass them to the "),R=o("code"),le=a("TFAutoModelForTokenClassification.from_pretrained()"),ue=a(" method, and they will be set in the model\u2019s configuration, then properly saved and uploaded to the Hub:"),ye=c(),j(ne.$$.fragment),Fe=c(),V=o("p"),nt=a("Like when we defined our "),pe=o("code"),dt=a("TFAutoModelForSequenceClassification"),Qt=a(" in "),ot=o("a"),ea=a("Chapter 3"),Tt=a(", creating the model issues a warning that some weights were not used (the ones from the pretraining head) and some other weights are randomly initialized (the ones from the new token classification head), and that this model should be trained. We will do that in a minute, but first let\u2019s double-check that our model has the right number of labels:"),es=c(),j(we.$$.fragment),Es=c(),j(Te.$$.fragment),fe=c(),j(Ye.$$.fragment),ts=c(),se=o("h3"),ce=o("a"),ss=o("span"),j(Le.$$.fragment),Dt=c(),as=o("span"),ta=a("Fine-tuning the model"),Xe=c(),Re=o("p"),Pt=a("We are now ready to train our model! We have just a little more housekeeping to do first, though: we should log in to Hugging Face and define our training hyperparameters. If you\u2019re working in a notebook, there\u2019s a convenience function to help you with this:"),ls=c(),j(zt.$$.fragment),xs=c(),je=o("p"),De=a("This will display a widget where you can enter your Hugging Face login credentials."),qt=c(),Ee=o("p"),Da=a("If you aren\u2019t working in a notebook, just type the following line in your terminal:"),At=c(),j(Ze.$$.fragment),Os=c(),ie=o("p"),It=a("After logging in, we can prepare everything we need to compile our model. \u{1F917} Transformers provides a convenient "),Ke=o("code"),ut=a("create_optimizer()"),Pa=a(" function that will give you an "),ft=o("code"),mt=a("AdamW"),sa=a(" optimizer with appropriate settings for the weight decay and learning rate decay, both of which will improve your model\u2019s performance compared to the built-in "),Pe=o("code"),ze=a("Adam"),ns=a(" optimizer:"),te=c(),j(Nt.$$.fragment),_t=c(),Ve=o("p"),aa=a("Note also that we don\u2019t supply a "),qe=o("code"),za=a("loss"),Cs=a(" argument to "),Je=o("code"),Ts=a("compile()"),la=a(". This is because the models can actually compute loss internally \u2014 if you compile without a loss and supply your labels in the input dictionary (as we do in our datasets), then the model will train using that internal loss, which will be appropriate for the task and model type you have chosen."),bt=c(),rt=o("p"),Qe=a("Next, we define a "),Ds=o("code"),os=a("PushToHubCallback"),Ps=a(" to upload our model to the Hub during training, and fit the model with that callback:"),na=c(),j(wt.$$.fragment),et=c(),me=o("p"),St=a("You can specify the full name of the repository you want to push to with the "),Ft=o("code"),Ae=a("hub_model_id"),oa=a(" argument (in particular, you will have to use this argument to push to an organization). For instance, when we pushed the model to the "),_e=o("a"),zs=o("code"),qs=a("huggingface-course"),ra=a(" organization"),rs=a(", we added "),is=o("code"),gt=a('hub_model_id="huggingface-course/bert-finetuned-ner"'),vt=a(". By default, the repository used will be in your namespace and named after the output directory you set, for example "),it=o("code"),Lt=a('"cool_huggingface_user/bert-finetuned-ner"'),As=a("."),Ie=c(),j(Rt.$$.fragment),Bt=c(),tt=o("p"),ia=a("Note that while the training happens, each time the model is saved (here, every epoch) it is uploaded to the Hub in the background. This way, you will be able to to resume your training on another machine if necessary."),pt=c(),Be=o("p"),ct=a("At this stage, you can use the inference widget on the Model Hub to test your model and share it with your friends. You have successfully fine-tuned a model on a token classification task \u2014 congratulations! But how good is our model, really? We should evaluate some metrics to find out."),this.h()},l(f){d=r(f,"H3",{class:!0});var L=i(d);g=r(L,"A",{id:!0,class:!0,href:!0});var ps=i(g);m=r(ps,"SPAN",{});var pa=i(m);E($.$$.fragment,pa),pa.forEach(s),ps.forEach(s),T=h(L),v=r(L,"SPAN",{});var Me=i(v);y=l(Me,"Defining the model"),Me.forEach(s),L.forEach(s),D=h(f),z=r(f,"P",{});var Ht=i(z);N=l(Ht,"Since we are working on a token classification problem, we will use the "),B=r(Ht,"CODE",{});var kt=i(B);A=l(kt,"TFAutoModelForTokenClassification"),kt.forEach(s),I=l(Ht," class. The main thing to remember when defining this model is to pass along some information on the number of labels we have. The easiest way to do this is to pass that number with the "),M=r(Ht,"CODE",{});var qa=i(M);G=l(qa,"num_labels"),qa.forEach(s),Z=l(Ht," argument, but if we want a nice inference widget working like the one we saw at the beginning of this section, it\u2019s better to set the correct label correspondences instead."),Ht.forEach(s),X=h(f),C=r(f,"P",{});var re=i(C);S=l(re,"They should be set by two dictionaries, "),P=r(re,"CODE",{});var Aa=i(P);H=l(Aa,"id2label"),Aa.forEach(s),F=l(re," and "),Y=r(re,"CODE",{});var Wt=i(Y);Q=l(Wt,"label2id"),Wt.forEach(s),ee=l(re,", which contain the mapping from ID to label and vice versa:"),re.forEach(s),oe=h(f),E(K.$$.fragment,f),de=h(f),J=r(f,"P",{});var ca=i(J);W=l(ca,"Now we can just pass them to the "),R=r(ca,"CODE",{});var Ia=i(R);le=l(Ia,"TFAutoModelForTokenClassification.from_pretrained()"),Ia.forEach(s),ue=l(ca," method, and they will be set in the model\u2019s configuration, then properly saved and uploaded to the Hub:"),ca.forEach(s),ye=h(f),E(ne.$$.fragment,f),Fe=h(f),V=r(f,"P",{});var ge=i(V);nt=l(ge,"Like when we defined our "),pe=r(ge,"CODE",{});var Gt=i(pe);dt=l(Gt,"TFAutoModelForSequenceClassification"),Gt.forEach(s),Qt=l(ge," in "),ot=r(ge,"A",{href:!0});var ha=i(ot);ea=l(ha,"Chapter 3"),ha.forEach(s),Tt=l(ge,", creating the model issues a warning that some weights were not used (the ones from the pretraining head) and some other weights are randomly initialized (the ones from the new token classification head), and that this model should be trained. We will do that in a minute, but first let\u2019s double-check that our model has the right number of labels:"),ge.forEach(s),es=h(f),E(we.$$.fragment,f),Es=h(f),E(Te.$$.fragment,f),fe=h(f),E(Ye.$$.fragment,f),ts=h(f),se=r(f,"H3",{class:!0});var st=i(se);ce=r(st,"A",{id:!0,class:!0,href:!0});var pl=i(ce);ss=r(pl,"SPAN",{});var da=i(ss);E(Le.$$.fragment,da),da.forEach(s),pl.forEach(s),Dt=h(st),as=r(st,"SPAN",{});var ua=i(as);ta=l(ua,"Fine-tuning the model"),ua.forEach(s),st.forEach(s),Xe=h(f),Re=r(f,"P",{});var Na=i(Re);Pt=l(Na,"We are now ready to train our model! We have just a little more housekeeping to do first, though: we should log in to Hugging Face and define our training hyperparameters. If you\u2019re working in a notebook, there\u2019s a convenience function to help you with this:"),Na.forEach(s),ls=h(f),E(zt.$$.fragment,f),xs=h(f),je=r(f,"P",{});var Ut=i(je);De=l(Ut,"This will display a widget where you can enter your Hugging Face login credentials."),Ut.forEach(s),qt=h(f),Ee=r(f,"P",{});var fa=i(Ee);Da=l(fa,"If you aren\u2019t working in a notebook, just type the following line in your terminal:"),fa.forEach(s),At=h(f),E(Ze.$$.fragment,f),Os=h(f),ie=r(f,"P",{});var He=i(ie);It=l(He,"After logging in, we can prepare everything we need to compile our model. \u{1F917} Transformers provides a convenient "),Ke=r(He,"CODE",{});var cl=i(Ke);ut=l(cl,"create_optimizer()"),cl.forEach(s),Pa=l(He," function that will give you an "),ft=r(He,"CODE",{});var Sa=i(ft);mt=l(Sa,"AdamW"),Sa.forEach(s),sa=l(He," optimizer with appropriate settings for the weight decay and learning rate decay, both of which will improve your model\u2019s performance compared to the built-in "),Pe=r(He,"CODE",{});var Yt=i(Pe);ze=l(Yt,"Adam"),Yt.forEach(s),ns=l(He," optimizer:"),He.forEach(s),te=h(f),E(Nt.$$.fragment,f),_t=h(f),Ve=r(f,"P",{});var xe=i(Ve);aa=l(xe,"Note also that we don\u2019t supply a "),qe=r(xe,"CODE",{});var We=i(qe);za=l(We,"loss"),We.forEach(s),Cs=l(xe," argument to "),Je=r(xe,"CODE",{});var Is=i(Je);Ts=l(Is,"compile()"),Is.forEach(s),la=l(xe,". This is because the models can actually compute loss internally \u2014 if you compile without a loss and supply your labels in the input dictionary (as we do in our datasets), then the model will train using that internal loss, which will be appropriate for the task and model type you have chosen."),xe.forEach(s),bt=h(f),rt=r(f,"P",{});var be=i(rt);Qe=l(be,"Next, we define a "),Ds=r(be,"CODE",{});var hl=i(Ds);os=l(hl,"PushToHubCallback"),hl.forEach(s),Ps=l(be," to upload our model to the Hub during training, and fit the model with that callback:"),be.forEach(s),na=h(f),E(wt.$$.fragment,f),et=h(f),me=r(f,"P",{});var ve=i(me);St=l(ve,"You can specify the full name of the repository you want to push to with the "),Ft=r(ve,"CODE",{});var dl=i(Ft);Ae=l(dl,"hub_model_id"),dl.forEach(s),oa=l(ve," argument (in particular, you will have to use this argument to push to an organization). For instance, when we pushed the model to the "),_e=r(ve,"A",{href:!0,rel:!0});var ma=i(_e);zs=r(ma,"CODE",{});var ke=i(zs);qs=l(ke,"huggingface-course"),ke.forEach(s),ra=l(ma," organization"),ma.forEach(s),rs=l(ve,", we added "),is=r(ve,"CODE",{});var ul=i(is);gt=l(ul,'hub_model_id="huggingface-course/bert-finetuned-ner"'),ul.forEach(s),vt=l(ve,". By default, the repository used will be in your namespace and named after the output directory you set, for example "),it=r(ve,"CODE",{});var _a=i(it);Lt=l(_a,'"cool_huggingface_user/bert-finetuned-ner"'),_a.forEach(s),As=l(ve,"."),ve.forEach(s),Ie=h(f),E(Rt.$$.fragment,f),Bt=h(f),tt=r(f,"P",{});var Fa=i(tt);ia=l(Fa,"Note that while the training happens, each time the model is saved (here, every epoch) it is uploaded to the Hub in the background. This way, you will be able to to resume your training on another machine if necessary."),Fa.forEach(s),pt=h(f),Be=r(f,"P",{});var Oe=i(Be);ct=l(Oe,"At this stage, you can use the inference widget on the Model Hub to test your model and share it with your friends. You have successfully fine-tuned a model on a token classification task \u2014 congratulations! But how good is our model, really? We should evaluate some metrics to find out."),Oe.forEach(s),this.h()},h(){k(g,"id","defining-the-model"),k(g,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(g,"href","#defining-the-model"),k(d,"class","relative group"),k(ot,"href","/course/chapter3"),k(ce,"id","finetuning-the-model"),k(ce,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(ce,"href","#finetuning-the-model"),k(se,"class","relative group"),k(_e,"href","https://huggingface.co/huggingface-course"),k(_e,"rel","nofollow")},m(f,L){p(f,d,L),t(d,g),t(g,m),x($,m,null),t(d,T),t(d,v),t(v,y),p(f,D,L),p(f,z,L),t(z,N),t(z,B),t(B,A),t(z,I),t(z,M),t(M,G),t(z,Z),p(f,X,L),p(f,C,L),t(C,S),t(C,P),t(P,H),t(C,F),t(C,Y),t(Y,Q),t(C,ee),p(f,oe,L),x(K,f,L),p(f,de,L),p(f,J,L),t(J,W),t(J,R),t(R,le),t(J,ue),p(f,ye,L),x(ne,f,L),p(f,Fe,L),p(f,V,L),t(V,nt),t(V,pe),t(pe,dt),t(V,Qt),t(V,ot),t(ot,ea),t(V,Tt),p(f,es,L),x(we,f,L),p(f,Es,L),x(Te,f,L),p(f,fe,L),x(Ye,f,L),p(f,ts,L),p(f,se,L),t(se,ce),t(ce,ss),x(Le,ss,null),t(se,Dt),t(se,as),t(as,ta),p(f,Xe,L),p(f,Re,L),t(Re,Pt),p(f,ls,L),x(zt,f,L),p(f,xs,L),p(f,je,L),t(je,De),p(f,qt,L),p(f,Ee,L),t(Ee,Da),p(f,At,L),x(Ze,f,L),p(f,Os,L),p(f,ie,L),t(ie,It),t(ie,Ke),t(Ke,ut),t(ie,Pa),t(ie,ft),t(ft,mt),t(ie,sa),t(ie,Pe),t(Pe,ze),t(ie,ns),p(f,te,L),x(Nt,f,L),p(f,_t,L),p(f,Ve,L),t(Ve,aa),t(Ve,qe),t(qe,za),t(Ve,Cs),t(Ve,Je),t(Je,Ts),t(Ve,la),p(f,bt,L),p(f,rt,L),t(rt,Qe),t(rt,Ds),t(Ds,os),t(rt,Ps),p(f,na,L),x(wt,f,L),p(f,et,L),p(f,me,L),t(me,St),t(me,Ft),t(Ft,Ae),t(me,oa),t(me,_e),t(_e,zs),t(zs,qs),t(_e,ra),t(me,rs),t(me,is),t(is,gt),t(me,vt),t(me,it),t(it,Lt),t(me,As),p(f,Ie,L),x(Rt,f,L),p(f,Bt,L),p(f,tt,L),t(tt,ia),p(f,pt,L),p(f,Be,L),t(Be,ct),Mt=!0},i(f){Mt||(b($.$$.fragment,f),b(K.$$.fragment,f),b(ne.$$.fragment,f),b(we.$$.fragment,f),b(Te.$$.fragment,f),b(Ye.$$.fragment,f),b(Le.$$.fragment,f),b(zt.$$.fragment,f),b(Ze.$$.fragment,f),b(Nt.$$.fragment,f),b(wt.$$.fragment,f),b(Rt.$$.fragment,f),Mt=!0)},o(f){w($.$$.fragment,f),w(K.$$.fragment,f),w(ne.$$.fragment,f),w(we.$$.fragment,f),w(Te.$$.fragment,f),w(Ye.$$.fragment,f),w(Le.$$.fragment,f),w(zt.$$.fragment,f),w(Ze.$$.fragment,f),w(Nt.$$.fragment,f),w(wt.$$.fragment,f),w(Rt.$$.fragment,f),Mt=!1},d(f){f&&s(d),O($),f&&s(D),f&&s(z),f&&s(X),f&&s(C),f&&s(oe),O(K,f),f&&s(de),f&&s(J),f&&s(ye),O(ne,f),f&&s(Fe),f&&s(V),f&&s(es),O(we,f),f&&s(Es),O(Te,f),f&&s(fe),O(Ye,f),f&&s(ts),f&&s(se),O(Le),f&&s(Xe),f&&s(Re),f&&s(ls),O(zt,f),f&&s(xs),f&&s(je),f&&s(qt),f&&s(Ee),f&&s(At),O(Ze,f),f&&s(Os),f&&s(ie),f&&s(te),O(Nt,f),f&&s(_t),f&&s(Ve),f&&s(bt),f&&s(rt),f&&s(na),O(wt,f),f&&s(et),f&&s(me),f&&s(Ie),O(Rt,f),f&&s(Bt),f&&s(tt),f&&s(pt),f&&s(Be)}}}function Td(U){let d,g,m,$,T;return{c(){d=o("p"),g=a("\u26A0\uFE0F If you have a model with the wrong number of labels, you will get an obscure error when calling "),m=o("code"),$=a("model.fit()"),T=a(" later. This can be annoying to debug, so make sure you do this check to confirm you have the expected number of labels.")},l(v){d=r(v,"P",{});var y=i(d);g=l(y,"\u26A0\uFE0F If you have a model with the wrong number of labels, you will get an obscure error when calling "),m=r(y,"CODE",{});var D=i(m);$=l(D,"model.fit()"),D.forEach(s),T=l(y," later. This can be annoying to debug, so make sure you do this check to confirm you have the expected number of labels."),y.forEach(s)},m(v,y){p(v,d,y),t(d,g),t(d,m),t(m,$),t(d,T)},d(v){v&&s(d)}}}function Dd(U){let d,g,m,$,T;return{c(){d=o("p"),g=a("\u{1F4A1} If the output directory you are using already exists, it needs to be a local clone of the repository you want to push to. If it isn\u2019t, you\u2019ll get an error when calling "),m=o("code"),$=a("model.fit()"),T=a(" and will need to set a new name.")},l(v){d=r(v,"P",{});var y=i(d);g=l(y,"\u{1F4A1} If the output directory you are using already exists, it needs to be a local clone of the repository you want to push to. If it isn\u2019t, you\u2019ll get an error when calling "),m=r(y,"CODE",{});var D=i(m);$=l(D,"model.fit()"),D.forEach(s),T=l(y," and will need to set a new name."),y.forEach(s)},m(v,y){p(v,d,y),t(d,g),t(d,m),t(m,$),t(d,T)},d(v){v&&s(d)}}}function Pd(U){let d,g,m,$,T,v,y,D,z,N,B,A,I,M,G,Z,X,C,S,P,H;return B=new q({props:{code:"!pip install seqeval",highlighted:"!pip install seqeval"}}),{c(){d=o("p"),g=a("The traditional framework used to evaluate token classification prediction is "),m=o("a"),$=o("em"),T=a("seqeval"),v=a(". To use this metric, we first need to install the "),y=o("em"),D=a("seqeval"),z=a(" library:"),N=c(),j(B.$$.fragment),A=c(),I=o("p"),M=a("We can then load it via the "),G=o("code"),Z=a("evaluate.load()"),X=a(" function like we did in "),C=o("a"),S=a("Chapter 3"),P=a(":"),this.h()},l(F){d=r(F,"P",{});var Y=i(d);g=l(Y,"The traditional framework used to evaluate token classification prediction is "),m=r(Y,"A",{href:!0,rel:!0});var Q=i(m);$=r(Q,"EM",{});var ee=i($);T=l(ee,"seqeval"),ee.forEach(s),Q.forEach(s),v=l(Y,". To use this metric, we first need to install the "),y=r(Y,"EM",{});var oe=i(y);D=l(oe,"seqeval"),oe.forEach(s),z=l(Y," library:"),Y.forEach(s),N=h(F),E(B.$$.fragment,F),A=h(F),I=r(F,"P",{});var K=i(I);M=l(K,"We can then load it via the "),G=r(K,"CODE",{});var de=i(G);Z=l(de,"evaluate.load()"),de.forEach(s),X=l(K," function like we did in "),C=r(K,"A",{href:!0});var J=i(C);S=l(J,"Chapter 3"),J.forEach(s),P=l(K,":"),K.forEach(s),this.h()},h(){k(m,"href","https://github.com/chakki-works/seqeval"),k(m,"rel","nofollow"),k(C,"href","/course/chapter3")},m(F,Y){p(F,d,Y),t(d,g),t(d,m),t(m,$),t($,T),t(d,v),t(d,y),t(y,D),t(d,z),p(F,N,Y),x(B,F,Y),p(F,A,Y),p(F,I,Y),t(I,M),t(I,G),t(G,Z),t(I,X),t(I,C),t(C,S),t(I,P),H=!0},i(F){H||(b(B.$$.fragment,F),H=!0)},o(F){w(B.$$.fragment,F),H=!1},d(F){F&&s(d),F&&s(N),O(B,F),F&&s(A),F&&s(I)}}}function zd(U){let d,g,m,$,T,v,y,D,z,N,B,A,I,M,G,Z,X,C,S,P,H,F,Y,Q,ee,oe,K,de,J,W;return P=new q({props:{code:"!pip install seqeval",highlighted:"!pip install seqeval"}}),{c(){d=o("p"),g=a("To have the "),m=o("code"),$=a("Trainer"),T=a(" compute a metric every epoch, we will need to define a "),v=o("code"),y=a("compute_metrics()"),D=a(" function that takes the arrays of predictions and labels, and returns a dictionary with the metric names and values."),z=c(),N=o("p"),B=a("The traditional framework used to evaluate token classification prediction is "),A=o("a"),I=o("em"),M=a("seqeval"),G=a(". To use this metric, we first need to install the "),Z=o("em"),X=a("seqeval"),C=a(" library:"),S=c(),j(P.$$.fragment),H=c(),F=o("p"),Y=a("We can then load it via the "),Q=o("code"),ee=a("evaluate.load()"),oe=a(" function like we did in "),K=o("a"),de=a("Chapter 3"),J=a(":"),this.h()},l(R){d=r(R,"P",{});var le=i(d);g=l(le,"To have the "),m=r(le,"CODE",{});var ue=i(m);$=l(ue,"Trainer"),ue.forEach(s),T=l(le," compute a metric every epoch, we will need to define a "),v=r(le,"CODE",{});var ye=i(v);y=l(ye,"compute_metrics()"),ye.forEach(s),D=l(le," function that takes the arrays of predictions and labels, and returns a dictionary with the metric names and values."),le.forEach(s),z=h(R),N=r(R,"P",{});var ne=i(N);B=l(ne,"The traditional framework used to evaluate token classification prediction is "),A=r(ne,"A",{href:!0,rel:!0});var Fe=i(A);I=r(Fe,"EM",{});var V=i(I);M=l(V,"seqeval"),V.forEach(s),Fe.forEach(s),G=l(ne,". To use this metric, we first need to install the "),Z=r(ne,"EM",{});var nt=i(Z);X=l(nt,"seqeval"),nt.forEach(s),C=l(ne," library:"),ne.forEach(s),S=h(R),E(P.$$.fragment,R),H=h(R),F=r(R,"P",{});var pe=i(F);Y=l(pe,"We can then load it via the "),Q=r(pe,"CODE",{});var dt=i(Q);ee=l(dt,"evaluate.load()"),dt.forEach(s),oe=l(pe," function like we did in "),K=r(pe,"A",{href:!0});var Qt=i(K);de=l(Qt,"Chapter 3"),Qt.forEach(s),J=l(pe,":"),pe.forEach(s),this.h()},h(){k(A,"href","https://github.com/chakki-works/seqeval"),k(A,"rel","nofollow"),k(K,"href","/course/chapter3")},m(R,le){p(R,d,le),t(d,g),t(d,m),t(m,$),t(d,T),t(d,v),t(v,y),t(d,D),p(R,z,le),p(R,N,le),t(N,B),t(N,A),t(A,I),t(I,M),t(N,G),t(N,Z),t(Z,X),t(N,C),p(R,S,le),x(P,R,le),p(R,H,le),p(R,F,le),t(F,Y),t(F,Q),t(Q,ee),t(F,oe),t(F,K),t(K,de),t(F,J),W=!0},i(R){W||(b(P.$$.fragment,R),W=!0)},o(R){w(P.$$.fragment,R),W=!1},d(R){R&&s(d),R&&s(z),R&&s(N),R&&s(S),O(P,R),R&&s(H),R&&s(F)}}}function qd(U){let d,g,m,$,T,v,y,D,z,N,B,A,I,M,G,Z,X,C,S;return I=new q({props:{code:`import numpy as np

all_predictions = []
all_labels = []
for batch in tf_eval_dataset:
    logits = model.predict_on_batch(batch)["logits"]
    labels = batch["labels"]
    predictions = np.argmax(logits, axis=-1)
    for prediction, label in zip(predictions, labels):
        for predicted_idx, label_idx in zip(prediction, label):
            if label_idx == -100:
                continue
            all_predictions.append(label_names[predicted_idx])
            all_labels.append(label_names[label_idx])
metric.compute(predictions=[all_predictions], references=[all_labels])`,highlighted:`<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np

all_predictions = []
all_labels = []
<span class="hljs-keyword">for</span> batch <span class="hljs-keyword">in</span> tf_eval_dataset:
    logits = model.predict_on_batch(batch)[<span class="hljs-string">&quot;logits&quot;</span>]
    labels = batch[<span class="hljs-string">&quot;labels&quot;</span>]
    predictions = np.argmax(logits, axis=-<span class="hljs-number">1</span>)
    <span class="hljs-keyword">for</span> prediction, label <span class="hljs-keyword">in</span> <span class="hljs-built_in">zip</span>(predictions, labels):
        <span class="hljs-keyword">for</span> predicted_idx, label_idx <span class="hljs-keyword">in</span> <span class="hljs-built_in">zip</span>(prediction, label):
            <span class="hljs-keyword">if</span> label_idx == -<span class="hljs-number">100</span>:
                <span class="hljs-keyword">continue</span>
            all_predictions.append(label_names[predicted_idx])
            all_labels.append(label_names[label_idx])
metric.compute(predictions=[all_predictions], references=[all_labels])`}}),G=new q({props:{code:`{'LOC': {'precision': 0.91, 'recall': 0.92, 'f1': 0.91, 'number': 1668},
 'MISC': {'precision': 0.70, 'recall': 0.79, 'f1': 0.74, 'number': 702},
 'ORG': {'precision': 0.85, 'recall': 0.90, 'f1': 0.88, 'number': 1661},
 'PER': {'precision': 0.95, 'recall': 0.95, 'f1': 0.95, 'number': 1617},
 'overall_precision': 0.87,
 'overall_recall': 0.91,
 'overall_f1': 0.89,
 'overall_accuracy': 0.97}`,highlighted:`{<span class="hljs-string">&#x27;LOC&#x27;</span>: {<span class="hljs-string">&#x27;precision&#x27;</span>: <span class="hljs-number">0.91</span>, <span class="hljs-string">&#x27;recall&#x27;</span>: <span class="hljs-number">0.92</span>, <span class="hljs-string">&#x27;f1&#x27;</span>: <span class="hljs-number">0.91</span>, <span class="hljs-string">&#x27;number&#x27;</span>: <span class="hljs-number">1668</span>},
 <span class="hljs-string">&#x27;MISC&#x27;</span>: {<span class="hljs-string">&#x27;precision&#x27;</span>: <span class="hljs-number">0.70</span>, <span class="hljs-string">&#x27;recall&#x27;</span>: <span class="hljs-number">0.79</span>, <span class="hljs-string">&#x27;f1&#x27;</span>: <span class="hljs-number">0.74</span>, <span class="hljs-string">&#x27;number&#x27;</span>: <span class="hljs-number">702</span>},
 <span class="hljs-string">&#x27;ORG&#x27;</span>: {<span class="hljs-string">&#x27;precision&#x27;</span>: <span class="hljs-number">0.85</span>, <span class="hljs-string">&#x27;recall&#x27;</span>: <span class="hljs-number">0.90</span>, <span class="hljs-string">&#x27;f1&#x27;</span>: <span class="hljs-number">0.88</span>, <span class="hljs-string">&#x27;number&#x27;</span>: <span class="hljs-number">1661</span>},
 <span class="hljs-string">&#x27;PER&#x27;</span>: {<span class="hljs-string">&#x27;precision&#x27;</span>: <span class="hljs-number">0.95</span>, <span class="hljs-string">&#x27;recall&#x27;</span>: <span class="hljs-number">0.95</span>, <span class="hljs-string">&#x27;f1&#x27;</span>: <span class="hljs-number">0.95</span>, <span class="hljs-string">&#x27;number&#x27;</span>: <span class="hljs-number">1617</span>},
 <span class="hljs-string">&#x27;overall_precision&#x27;</span>: <span class="hljs-number">0.87</span>,
 <span class="hljs-string">&#x27;overall_recall&#x27;</span>: <span class="hljs-number">0.91</span>,
 <span class="hljs-string">&#x27;overall_f1&#x27;</span>: <span class="hljs-number">0.89</span>,
 <span class="hljs-string">&#x27;overall_accuracy&#x27;</span>: <span class="hljs-number">0.97</span>}`}}),{c(){d=o("p"),g=a("This is sending back a lot of information! We get the precision, recall, and F1 score for each separate entity, as well as overall. Now let\u2019s see what happens if we try using our actual model predictions to compute some real scores."),m=c(),$=o("p"),T=a("TensorFlow doesn\u2019t like concatenating our predictions together, because they have variable sequence lengths. This means we can\u2019t just use "),v=o("code"),y=a("model.predict()"),D=a(" \u2014 but that\u2019s not going to stop us. We\u2019ll get some predictions a batch at a time and concatenate them into one big long list as we go, dropping the "),z=o("code"),N=a("-100"),B=a(" tokens that indicate masking/padding, then compute metrics on the list at the end:"),A=c(),j(I.$$.fragment),M=c(),j(G.$$.fragment),Z=c(),X=o("p"),C=a("How did your model do, compared to ours? If you got similar numbers, your training was a success!")},l(P){d=r(P,"P",{});var H=i(d);g=l(H,"This is sending back a lot of information! We get the precision, recall, and F1 score for each separate entity, as well as overall. Now let\u2019s see what happens if we try using our actual model predictions to compute some real scores."),H.forEach(s),m=h(P),$=r(P,"P",{});var F=i($);T=l(F,"TensorFlow doesn\u2019t like concatenating our predictions together, because they have variable sequence lengths. This means we can\u2019t just use "),v=r(F,"CODE",{});var Y=i(v);y=l(Y,"model.predict()"),Y.forEach(s),D=l(F," \u2014 but that\u2019s not going to stop us. We\u2019ll get some predictions a batch at a time and concatenate them into one big long list as we go, dropping the "),z=r(F,"CODE",{});var Q=i(z);N=l(Q,"-100"),Q.forEach(s),B=l(F," tokens that indicate masking/padding, then compute metrics on the list at the end:"),F.forEach(s),A=h(P),E(I.$$.fragment,P),M=h(P),E(G.$$.fragment,P),Z=h(P),X=r(P,"P",{});var ee=i(X);C=l(ee,"How did your model do, compared to ours? If you got similar numbers, your training was a success!"),ee.forEach(s)},m(P,H){p(P,d,H),t(d,g),p(P,m,H),p(P,$,H),t($,T),t($,v),t(v,y),t($,D),t($,z),t(z,N),t($,B),p(P,A,H),x(I,P,H),p(P,M,H),x(G,P,H),p(P,Z,H),p(P,X,H),t(X,C),S=!0},i(P){S||(b(I.$$.fragment,P),b(G.$$.fragment,P),S=!0)},o(P){w(I.$$.fragment,P),w(G.$$.fragment,P),S=!1},d(P){P&&s(d),P&&s(m),P&&s($),P&&s(A),O(I,P),P&&s(M),O(G,P),P&&s(Z),P&&s(X)}}}function Ad(U){let d,g,m,$,T,v,y,D,z,N,B,A,I,M,G,Z,X,C,S,P,H,F,Y,Q,ee,oe,K,de,J;return S=new q({props:{code:`import numpy as np


def compute_metrics(eval_preds):
    logits, labels = eval_preds
    predictions = np.argmax(logits, axis=-1)

    # Remove ignored index (special tokens) and convert to labels
    true_labels = [[label_names[l] for l in label if l != -100] for label in labels]
    true_predictions = [
        [label_names[p] for (p, l) in zip(prediction, label) if l != -100]
        for prediction, label in zip(predictions, labels)
    ]
    all_metrics = metric.compute(predictions=true_predictions, references=true_labels)
    return {
        "precision": all_metrics["overall_precision"],
        "recall": all_metrics["overall_recall"],
        "f1": all_metrics["overall_f1"],
        "accuracy": all_metrics["overall_accuracy"],
    }`,highlighted:`<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np


<span class="hljs-keyword">def</span> <span class="hljs-title function_">compute_metrics</span>(<span class="hljs-params">eval_preds</span>):
    logits, labels = eval_preds
    predictions = np.argmax(logits, axis=-<span class="hljs-number">1</span>)

    <span class="hljs-comment"># Remove ignored index (special tokens) and convert to labels</span>
    true_labels = [[label_names[l] <span class="hljs-keyword">for</span> l <span class="hljs-keyword">in</span> label <span class="hljs-keyword">if</span> l != -<span class="hljs-number">100</span>] <span class="hljs-keyword">for</span> label <span class="hljs-keyword">in</span> labels]
    true_predictions = [
        [label_names[p] <span class="hljs-keyword">for</span> (p, l) <span class="hljs-keyword">in</span> <span class="hljs-built_in">zip</span>(prediction, label) <span class="hljs-keyword">if</span> l != -<span class="hljs-number">100</span>]
        <span class="hljs-keyword">for</span> prediction, label <span class="hljs-keyword">in</span> <span class="hljs-built_in">zip</span>(predictions, labels)
    ]
    all_metrics = metric.compute(predictions=true_predictions, references=true_labels)
    <span class="hljs-keyword">return</span> {
        <span class="hljs-string">&quot;precision&quot;</span>: all_metrics[<span class="hljs-string">&quot;overall_precision&quot;</span>],
        <span class="hljs-string">&quot;recall&quot;</span>: all_metrics[<span class="hljs-string">&quot;overall_recall&quot;</span>],
        <span class="hljs-string">&quot;f1&quot;</span>: all_metrics[<span class="hljs-string">&quot;overall_f1&quot;</span>],
        <span class="hljs-string">&quot;accuracy&quot;</span>: all_metrics[<span class="hljs-string">&quot;overall_accuracy&quot;</span>],
    }`}}),{c(){d=o("p"),g=a("This is sending back a lot of information! We get the precision, recall, and F1 score for each separate entity, as well as overall. For our metric computation we will only keep the overall score, but feel free to tweak the "),m=o("code"),$=a("compute_metrics()"),T=a(" function to return all the metrics you would like reported."),v=c(),y=o("p"),D=a("This "),z=o("code"),N=a("compute_metrics()"),B=a(" function first takes the argmax of the logits to convert them to predictions (as usual, the logits and the probabilities are in the same order, so we don\u2019t need to apply the softmax). Then we have to convert both labels and predictions from integers to strings. We remove all the values where the label is "),A=o("code"),I=a("-100"),M=a(", then pass the results to the "),G=o("code"),Z=a("metric.compute()"),X=a(" method:"),C=c(),j(S.$$.fragment),P=c(),H=o("p"),F=a("Now that this is done, we are almost ready to define our "),Y=o("code"),Q=a("Trainer"),ee=a(". We just need a "),oe=o("code"),K=a("model"),de=a(" to fine-tune!")},l(W){d=r(W,"P",{});var R=i(d);g=l(R,"This is sending back a lot of information! We get the precision, recall, and F1 score for each separate entity, as well as overall. For our metric computation we will only keep the overall score, but feel free to tweak the "),m=r(R,"CODE",{});var le=i(m);$=l(le,"compute_metrics()"),le.forEach(s),T=l(R," function to return all the metrics you would like reported."),R.forEach(s),v=h(W),y=r(W,"P",{});var ue=i(y);D=l(ue,"This "),z=r(ue,"CODE",{});var ye=i(z);N=l(ye,"compute_metrics()"),ye.forEach(s),B=l(ue," function first takes the argmax of the logits to convert them to predictions (as usual, the logits and the probabilities are in the same order, so we don\u2019t need to apply the softmax). Then we have to convert both labels and predictions from integers to strings. We remove all the values where the label is "),A=r(ue,"CODE",{});var ne=i(A);I=l(ne,"-100"),ne.forEach(s),M=l(ue,", then pass the results to the "),G=r(ue,"CODE",{});var Fe=i(G);Z=l(Fe,"metric.compute()"),Fe.forEach(s),X=l(ue," method:"),ue.forEach(s),C=h(W),E(S.$$.fragment,W),P=h(W),H=r(W,"P",{});var V=i(H);F=l(V,"Now that this is done, we are almost ready to define our "),Y=r(V,"CODE",{});var nt=i(Y);Q=l(nt,"Trainer"),nt.forEach(s),ee=l(V,". We just need a "),oe=r(V,"CODE",{});var pe=i(oe);K=l(pe,"model"),pe.forEach(s),de=l(V," to fine-tune!"),V.forEach(s)},m(W,R){p(W,d,R),t(d,g),t(d,m),t(m,$),t(d,T),p(W,v,R),p(W,y,R),t(y,D),t(y,z),t(z,N),t(y,B),t(y,A),t(A,I),t(y,M),t(y,G),t(G,Z),t(y,X),p(W,C,R),x(S,W,R),p(W,P,R),p(W,H,R),t(H,F),t(H,Y),t(Y,Q),t(H,ee),t(H,oe),t(oe,K),t(H,de),J=!0},i(W){J||(b(S.$$.fragment,W),J=!0)},o(W){w(S.$$.fragment,W),J=!1},d(W){W&&s(d),W&&s(v),W&&s(y),W&&s(C),O(S,W),W&&s(P),W&&s(H)}}}function cd(U){let d,g,m,$,T,v,y,D,z,N,B,A,I,M,G,Z,X,C,S,P,H,F,Y,Q,ee,oe,K,de,J,W,R,le,ue,ye,ne,Fe,V,nt,pe,dt,Qt,ot,ea,Tt,es,we,Es,Te,fe,Ye,ts,se,ce,ss,Le,Dt,as,ta,Xe,Re,Pt,ls,zt,xs,je,De,qt,Ee,Da,At,Ze,Os,ie,It,Ke,ut,Pa,ft,mt,sa,Pe,ze,ns,te,Nt,_t,Ve,aa,qe,za,Cs,Je,Ts,la,bt,rt,Qe,Ds,os,Ps,na,wt,et,me,St,Ft,Ae,oa,_e,zs,qs,ra,rs,is,gt,vt,it,Lt,As,Ie,Rt,Bt,tt,ia,pt,Be,ct,Mt,f,L,ps,pa,Me,Ht,kt,qa,re,Aa,Wt,ca,Ia,ge,Gt,ha,st,pl,da,ua,Na,Ut,fa,He,cl,Sa,Yt,xe,We,Is,be,hl,ve,dl,ma,ke,ul,_a,Fa,Oe,ba,Xl,Ro,Zl,Bo,cs,fl,La,Ln,wa,Mo,Rn,Ns,Bn,hs,Ho,$t,Kl,Wo,Vl,Jl,Go,Mn,Ss,Hn,ga,Uo,yt,Ql,Yo,Wn,Fs,Gn,Ra,ml,ds,Xo,en,us,tn,sn,Zo,an,Un,Ba,_l,jt,Ko,bl,wl,Vo,gl,Ma,Yn,Ls,Xn,fs,Zn,Rs,Kn,Ha,vl,kl,Jo,ln,Xt,nn,Ce,Qo,Wa,er,tr,Ga,sr,ar,on,at,Bs,Zt,Et,rn,Ms,lr,$l,ms,Vn,Hs,Jn,_s,pn,yl,nr,Qn,Ws,eo,jl,to,Gs,bs,Us,or,cn,so,Ua,ao,ae,rr,Ya,ir,pr,Ys,cr,hr,Xs,dr,ur,Xa,fr,mr,hn,Zs,_r,El,Za,lo,Ks,no,ws,oo,va,br,ro,Vs,io,xl,po,ka,$a,ya,he,Ne,dn,un,wr,fn,mn,gr,_n,bn,vr,wn,gn,kr,vn,kn,$r,$n,co,ja,yn,Ol,yr,ho,Kt,Ka,Cl,Va,uo,$e,jn,En,jr,fo;return $=new Ct({}),K=new q({props:{code:`id2label = {i: label for i, label in enumerate(label_names)}
label2id = {v: k for k, v in id2label.items()}`,highlighted:`id2label = {i: label <span class="hljs-keyword">for</span> i, label <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(label_names)}
label2id = {v: k <span class="hljs-keyword">for</span> k, v <span class="hljs-keyword">in</span> id2label.items()}`}}),ne=new q({props:{code:`from transformers import AutoModelForTokenClassification

model = AutoModelForTokenClassification.from_pretrained(
    model_checkpoint,
    id2label=id2label,
    label2id=label2id,
)`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoModelForTokenClassification

model = AutoModelForTokenClassification.from_pretrained(
    model_checkpoint,
    id2label=id2label,
    label2id=label2id,
)`}}),we=new q({props:{code:"model.config.num_labels",highlighted:"model.config.num_labels"}}),Te=new q({props:{code:"9",highlighted:'<span class="hljs-number">9</span>'}}),Ye=new Lo({props:{warning:!0,$$slots:{default:[Id]},$$scope:{ctx:U}}}),Le=new Ct({}),De=new q({props:{code:`from huggingface_hub import notebook_login

notebook_login()`,highlighted:`<span class="hljs-keyword">from</span> huggingface_hub <span class="hljs-keyword">import</span> notebook_login

notebook_login()`}}),It=new q({props:{code:"huggingface-cli login",highlighted:"huggingface-cli login"}}),ze=new q({props:{code:`from transformers import TrainingArguments

args = TrainingArguments(
    "bert-finetuned-ner",
    evaluation_strategy="epoch",
    save_strategy="epoch",
    learning_rate=2e-5,
    num_train_epochs=3,
    weight_decay=0.01,
    push_to_hub=True,
)`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> TrainingArguments

args = TrainingArguments(
    <span class="hljs-string">&quot;bert-finetuned-ner&quot;</span>,
    evaluation_strategy=<span class="hljs-string">&quot;epoch&quot;</span>,
    save_strategy=<span class="hljs-string">&quot;epoch&quot;</span>,
    learning_rate=<span class="hljs-number">2e-5</span>,
    num_train_epochs=<span class="hljs-number">3</span>,
    weight_decay=<span class="hljs-number">0.01</span>,
    push_to_hub=<span class="hljs-literal">True</span>,
)`}}),Ae=new Lo({props:{$$slots:{default:[Nd]},$$scope:{ctx:U}}}),gt=new q({props:{code:`from transformers import Trainer

trainer = Trainer(
    model=model,
    args=args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    data_collator=data_collator,
    compute_metrics=compute_metrics,
    tokenizer=tokenizer,
)
trainer.train()`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> Trainer

trainer = Trainer(
    model=model,
    args=args,
    train_dataset=tokenized_datasets[<span class="hljs-string">&quot;train&quot;</span>],
    eval_dataset=tokenized_datasets[<span class="hljs-string">&quot;validation&quot;</span>],
    data_collator=data_collator,
    compute_metrics=compute_metrics,
    tokenizer=tokenizer,
)
trainer.train()`}}),Be=new q({props:{code:'trainer.push_to_hub(commit_message="Training complete")',highlighted:'trainer.push_to_hub(commit_message=<span class="hljs-string">&quot;Training complete&quot;</span>)'}}),ps=new q({props:{code:"'https://huggingface.co/sgugger/bert-finetuned-ner/commit/26ab21e5b1568f9afeccdaed2d8715f571d786ed'",highlighted:'<span class="hljs-string">&#x27;https://huggingface.co/sgugger/bert-finetuned-ner/commit/26ab21e5b1568f9afeccdaed2d8715f571d786ed&#x27;</span>'}}),st=new Ct({}),be=new Ct({}),La=new q({props:{code:`from torch.utils.data import DataLoader

train_dataloader = DataLoader(
    tokenized_datasets["train"],
    shuffle=True,
    collate_fn=data_collator,
    batch_size=8,
)
eval_dataloader = DataLoader(
    tokenized_datasets["validation"], collate_fn=data_collator, batch_size=8
)`,highlighted:`<span class="hljs-keyword">from</span> torch.utils.data <span class="hljs-keyword">import</span> DataLoader

train_dataloader = DataLoader(
    tokenized_datasets[<span class="hljs-string">&quot;train&quot;</span>],
    shuffle=<span class="hljs-literal">True</span>,
    collate_fn=data_collator,
    batch_size=<span class="hljs-number">8</span>,
)
eval_dataloader = DataLoader(
    tokenized_datasets[<span class="hljs-string">&quot;validation&quot;</span>], collate_fn=data_collator, batch_size=<span class="hljs-number">8</span>
)`}}),Ns=new q({props:{code:`model = AutoModelForTokenClassification.from_pretrained(
    model_checkpoint,
    id2label=id2label,
    label2id=label2id,
)`,highlighted:`model = AutoModelForTokenClassification.from_pretrained(
    model_checkpoint,
    id2label=id2label,
    label2id=label2id,
)`}}),Ss=new q({props:{code:`from torch.optim import AdamW

optimizer = AdamW(model.parameters(), lr=2e-5)`,highlighted:`<span class="hljs-keyword">from</span> torch.optim <span class="hljs-keyword">import</span> AdamW

optimizer = AdamW(model.parameters(), lr=<span class="hljs-number">2e-5</span>)`}}),Fs=new q({props:{code:`from accelerate import Accelerator

accelerator = Accelerator()
model, optimizer, train_dataloader, eval_dataloader = accelerator.prepare(
    model, optimizer, train_dataloader, eval_dataloader
)`,highlighted:`<span class="hljs-keyword">from</span> accelerate <span class="hljs-keyword">import</span> Accelerator

accelerator = Accelerator()
model, optimizer, train_dataloader, eval_dataloader = accelerator.prepare(
    model, optimizer, train_dataloader, eval_dataloader
)`}}),Ra=new Lo({props:{$$slots:{default:[Sd]},$$scope:{ctx:U}}}),Ba=new q({props:{code:`from transformers import get_scheduler

num_train_epochs = 3
num_update_steps_per_epoch = len(train_dataloader)
num_training_steps = num_train_epochs * num_update_steps_per_epoch

lr_scheduler = get_scheduler(
    "linear",
    optimizer=optimizer,
    num_warmup_steps=0,
    num_training_steps=num_training_steps,
)`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> get_scheduler

num_train_epochs = <span class="hljs-number">3</span>
num_update_steps_per_epoch = <span class="hljs-built_in">len</span>(train_dataloader)
num_training_steps = num_train_epochs * num_update_steps_per_epoch

lr_scheduler = get_scheduler(
    <span class="hljs-string">&quot;linear&quot;</span>,
    optimizer=optimizer,
    num_warmup_steps=<span class="hljs-number">0</span>,
    num_training_steps=num_training_steps,
)`}}),Rs=new q({props:{code:`from huggingface_hub import Repository, get_full_repo_name

model_name = "bert-finetuned-ner-accelerate"
repo_name = get_full_repo_name(model_name)
repo_name`,highlighted:`<span class="hljs-keyword">from</span> huggingface_hub <span class="hljs-keyword">import</span> Repository, get_full_repo_name

model_name = <span class="hljs-string">&quot;bert-finetuned-ner-accelerate&quot;</span>
repo_name = get_full_repo_name(model_name)
repo_name`}}),Ha=new q({props:{code:"'sgugger/bert-finetuned-ner-accelerate'",highlighted:'<span class="hljs-string">&#x27;sgugger/bert-finetuned-ner-accelerate&#x27;</span>'}}),Xt=new q({props:{code:`output_dir = "bert-finetuned-ner-accelerate"
repo = Repository(output_dir, clone_from=repo_name)`,highlighted:`output_dir = <span class="hljs-string">&quot;bert-finetuned-ner-accelerate&quot;</span>
repo = Repository(output_dir, clone_from=repo_name)`}}),Et=new Ct({}),Ws=new q({props:{code:`def postprocess(predictions, labels):
    predictions = predictions.detach().cpu().clone().numpy()
    labels = labels.detach().cpu().clone().numpy()

    # Remove ignored index (special tokens) and convert to labels
    true_labels = [[label_names[l] for l in label if l != -100] for label in labels]
    true_predictions = [
        [label_names[p] for (p, l) in zip(prediction, label) if l != -100]
        for prediction, label in zip(predictions, labels)
    ]
    return true_labels, true_predictions`,highlighted:`<span class="hljs-keyword">def</span> <span class="hljs-title function_">postprocess</span>(<span class="hljs-params">predictions, labels</span>):
    predictions = predictions.detach().cpu().clone().numpy()
    labels = labels.detach().cpu().clone().numpy()

    <span class="hljs-comment"># Remove ignored index (special tokens) and convert to labels</span>
    true_labels = [[label_names[l] <span class="hljs-keyword">for</span> l <span class="hljs-keyword">in</span> label <span class="hljs-keyword">if</span> l != -<span class="hljs-number">100</span>] <span class="hljs-keyword">for</span> label <span class="hljs-keyword">in</span> labels]
    true_predictions = [
        [label_names[p] <span class="hljs-keyword">for</span> (p, l) <span class="hljs-keyword">in</span> <span class="hljs-built_in">zip</span>(prediction, label) <span class="hljs-keyword">if</span> l != -<span class="hljs-number">100</span>]
        <span class="hljs-keyword">for</span> prediction, label <span class="hljs-keyword">in</span> <span class="hljs-built_in">zip</span>(predictions, labels)
    ]
    <span class="hljs-keyword">return</span> true_labels, true_predictions`}}),Vs=new q({props:{code:`from tqdm.auto import tqdm
import torch

progress_bar = tqdm(range(num_training_steps))

for epoch in range(num_train_epochs):
    # Training
    model.train()
    for batch in train_dataloader:
        outputs = model(**batch)
        loss = outputs.loss
        accelerator.backward(loss)

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()
        progress_bar.update(1)

    # Evaluation
    model.eval()
    for batch in eval_dataloader:
        with torch.no_grad():
            outputs = model(**batch)

        predictions = outputs.logits.argmax(dim=-1)
        labels = batch["labels"]

        # Necessary to pad predictions and labels for being gathered
        predictions = accelerator.pad_across_processes(predictions, dim=1, pad_index=-100)
        labels = accelerator.pad_across_processes(labels, dim=1, pad_index=-100)

        predictions_gathered = accelerator.gather(predictions)
        labels_gathered = accelerator.gather(labels)

        true_predictions, true_labels = postprocess(predictions_gathered, labels_gathered)
        metric.add_batch(predictions=true_predictions, references=true_labels)

    results = metric.compute()
    print(
        f"epoch {epoch}:",
        {
            key: results[f"overall_{key}"]
            for key in ["precision", "recall", "f1", "accuracy"]
        },
    )

    # Save and upload
    accelerator.wait_for_everyone()
    unwrapped_model = accelerator.unwrap_model(model)
    unwrapped_model.save_pretrained(output_dir, save_function=accelerator.save)
    if accelerator.is_main_process:
        tokenizer.save_pretrained(output_dir)
        repo.push_to_hub(
            commit_message=f"Training in progress epoch {epoch}", blocking=False
        )`,highlighted:`<span class="hljs-keyword">from</span> tqdm.auto <span class="hljs-keyword">import</span> tqdm
<span class="hljs-keyword">import</span> torch

progress_bar = tqdm(<span class="hljs-built_in">range</span>(num_training_steps))

<span class="hljs-keyword">for</span> epoch <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num_train_epochs):
    <span class="hljs-comment"># Training</span>
    model.train()
    <span class="hljs-keyword">for</span> batch <span class="hljs-keyword">in</span> train_dataloader:
        outputs = model(**batch)
        loss = outputs.loss
        accelerator.backward(loss)

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()
        progress_bar.update(<span class="hljs-number">1</span>)

    <span class="hljs-comment"># Evaluation</span>
    model.<span class="hljs-built_in">eval</span>()
    <span class="hljs-keyword">for</span> batch <span class="hljs-keyword">in</span> eval_dataloader:
        <span class="hljs-keyword">with</span> torch.no_grad():
            outputs = model(**batch)

        predictions = outputs.logits.argmax(dim=-<span class="hljs-number">1</span>)
        labels = batch[<span class="hljs-string">&quot;labels&quot;</span>]

        <span class="hljs-comment"># Necessary to pad predictions and labels for being gathered</span>
        predictions = accelerator.pad_across_processes(predictions, dim=<span class="hljs-number">1</span>, pad_index=-<span class="hljs-number">100</span>)
        labels = accelerator.pad_across_processes(labels, dim=<span class="hljs-number">1</span>, pad_index=-<span class="hljs-number">100</span>)

        predictions_gathered = accelerator.gather(predictions)
        labels_gathered = accelerator.gather(labels)

        true_predictions, true_labels = postprocess(predictions_gathered, labels_gathered)
        metric.add_batch(predictions=true_predictions, references=true_labels)

    results = metric.compute()
    <span class="hljs-built_in">print</span>(
        <span class="hljs-string">f&quot;epoch <span class="hljs-subst">{epoch}</span>:&quot;</span>,
        {
            key: results[<span class="hljs-string">f&quot;overall_<span class="hljs-subst">{key}</span>&quot;</span>]
            <span class="hljs-keyword">for</span> key <span class="hljs-keyword">in</span> [<span class="hljs-string">&quot;precision&quot;</span>, <span class="hljs-string">&quot;recall&quot;</span>, <span class="hljs-string">&quot;f1&quot;</span>, <span class="hljs-string">&quot;accuracy&quot;</span>]
        },
    )

    <span class="hljs-comment"># Save and upload</span>
    accelerator.wait_for_everyone()
    unwrapped_model = accelerator.unwrap_model(model)
    unwrapped_model.save_pretrained(output_dir, save_function=accelerator.save)
    <span class="hljs-keyword">if</span> accelerator.is_main_process:
        tokenizer.save_pretrained(output_dir)
        repo.push_to_hub(
            commit_message=<span class="hljs-string">f&quot;Training in progress epoch <span class="hljs-subst">{epoch}</span>&quot;</span>, blocking=<span class="hljs-literal">False</span>
        )`}}),$a=new q({props:{code:`accelerator.wait_for_everyone()
unwrapped_model = accelerator.unwrap_model(model)
unwrapped_model.save_pretrained(output_dir, save_function=accelerator.save)`,highlighted:`accelerator.wait_for_everyone()
unwrapped_model = accelerator.unwrap_model(model)
unwrapped_model.save_pretrained(output_dir, save_function=accelerator.save)`}}),{c(){d=o("h3"),g=o("a"),m=o("span"),j($.$$.fragment),T=c(),v=o("span"),y=a("Defining the model"),D=c(),z=o("p"),N=a("Since we are working on a token classification problem, we will use the "),B=o("code"),A=a("AutoModelForTokenClassification"),I=a(" class. The main thing to remember when defining this model is to pass along some information on the number of labels we have. The easiest way to do this is to pass that number with the "),M=o("code"),G=a("num_labels"),Z=a(" argument, but if we want a nice inference widget working like the one we saw at the beginning of this section, it\u2019s better to set the correct label correspondences instead."),X=c(),C=o("p"),S=a("They should be set by two dictionaries, "),P=o("code"),H=a("id2label"),F=a(" and "),Y=o("code"),Q=a("label2id"),ee=a(", which contain the mappings from ID to label and vice versa:"),oe=c(),j(K.$$.fragment),de=c(),J=o("p"),W=a("Now we can just pass them to the "),R=o("code"),le=a("AutoModelForTokenClassification.from_pretrained()"),ue=a(" method, and they will be set in the model\u2019s configuration and then properly saved and uploaded to the Hub:"),ye=c(),j(ne.$$.fragment),Fe=c(),V=o("p"),nt=a("Like when we defined our "),pe=o("code"),dt=a("AutoModelForSequenceClassification"),Qt=a(" in "),ot=o("a"),ea=a("Chapter 3"),Tt=a(", creating the model issues a warning that some weights were not used (the ones from the pretraining head) and some other weights are randomly initialized (the ones from the new token classification head), and that this model should be trained. We will do that in a minute, but first let\u2019s double-check that our model has the right number of labels:"),es=c(),j(we.$$.fragment),Es=c(),j(Te.$$.fragment),fe=c(),j(Ye.$$.fragment),ts=c(),se=o("h3"),ce=o("a"),ss=o("span"),j(Le.$$.fragment),Dt=c(),as=o("span"),ta=a("Fine-tuning the model"),Xe=c(),Re=o("p"),Pt=a("We are now ready to train our model! We just need to do two last things before we define our "),ls=o("code"),zt=a("Trainer"),xs=a(": log in to Hugging Face and define our training arguments. If you\u2019re working in a notebook, there\u2019s a convenience function to help you with this:"),je=c(),j(De.$$.fragment),qt=c(),Ee=o("p"),Da=a("This will display a widget where you can enter your Hugging Face login credentials."),At=c(),Ze=o("p"),Os=a("If you aren\u2019t working in a notebook, just type the following line in your terminal:"),ie=c(),j(It.$$.fragment),Ke=c(),ut=o("p"),Pa=a("Once this is done, we can define our "),ft=o("code"),mt=a("TrainingArguments"),sa=a(":"),Pe=c(),j(ze.$$.fragment),ns=c(),te=o("p"),Nt=a("You\u2019ve seen most of those before: we set some hyperparameters (like the learning rate, the number of epochs to train for, and the weight decay), and we specify "),_t=o("code"),Ve=a("push_to_hub=True"),aa=a(" to indicate that we want to save the model and evaluate it at the end of every epoch, and that we want to upload our results to the Model Hub. Note that you can specify the name of the repository you want to push to with the "),qe=o("code"),za=a("hub_model_id"),Cs=a(" argument (in particular, you will have to use this argument to push to an organization). For instance, when we pushed the model to the "),Je=o("a"),Ts=o("code"),la=a("huggingface-course"),bt=a(" organization"),rt=a(", we added "),Qe=o("code"),Ds=a('hub_model_id="huggingface-course/bert-finetuned-ner"'),os=a(" to "),Ps=o("code"),na=a("TrainingArguments"),wt=a(". By default, the repository used will be in your namespace and named after the output directory you set, so in our case it will be "),et=o("code"),me=a('"sgugger/bert-finetuned-ner"'),St=a("."),Ft=c(),j(Ae.$$.fragment),oa=c(),_e=o("p"),zs=a("Finally, we just pass everything to the "),qs=o("code"),ra=a("Trainer"),rs=a(" and launch the training:"),is=c(),j(gt.$$.fragment),vt=c(),it=o("p"),Lt=a("Note that while the training happens, each time the model is saved (here, every epoch) it is uploaded to the Hub in the background. This way, you will be able to to resume your training on another machine if necessary."),As=c(),Ie=o("p"),Rt=a("Once the training is complete, we use the "),Bt=o("code"),tt=a("push_to_hub()"),ia=a(" method to make sure we upload the most recent version of the model:"),pt=c(),j(Be.$$.fragment),ct=c(),Mt=o("p"),f=a("This command returns the URL of the commit it just did, if you want to inspect it:"),L=c(),j(ps.$$.fragment),pa=c(),Me=o("p"),Ht=a("The "),kt=o("code"),qa=a("Trainer"),re=a(" also drafts a model card with all the evaluation results and uploads it. At this stage, you can use the inference widget on the Model Hub to test your model and share it with your friends. You have successfully fine-tuned a model on a token classification task \u2014 congratulations!"),Aa=c(),Wt=o("p"),ca=a("If you want to dive a bit more deeply into the training loop, we will now show you how to do the same thing using \u{1F917} Accelerate."),Ia=c(),ge=o("h2"),Gt=o("a"),ha=o("span"),j(st.$$.fragment),pl=c(),da=o("span"),ua=a("A custom training loop"),Na=c(),Ut=o("p"),fa=a("Let\u2019s now take a look at the full training loop, so you can easily customize the parts you need. It will look a lot like what we did in "),He=o("a"),cl=a("Chapter 3"),Sa=a(", with a few changes for the evaluation."),Yt=c(),xe=o("h3"),We=o("a"),Is=o("span"),j(be.$$.fragment),hl=c(),ve=o("span"),dl=a("Preparing everything for training"),ma=c(),ke=o("p"),ul=a("First we need to build the "),_a=o("code"),Fa=a("DataLoader"),Oe=a("s from our datasets. We\u2019ll reuse our "),ba=o("code"),Xl=a("data_collator"),Ro=a(" as a "),Zl=o("code"),Bo=a("collate_fn"),cs=a(" and shuffle the training set, but not the validation set:"),fl=c(),j(La.$$.fragment),Ln=c(),wa=o("p"),Mo=a("Next we reinstantiate our model, to make sure we\u2019re not continuing the fine-tuning from before but starting from the BERT pretrained model again:"),Rn=c(),j(Ns.$$.fragment),Bn=c(),hs=o("p"),Ho=a("Then we will need an optimizer. We\u2019ll use the classic "),$t=o("code"),Kl=a("AdamW"),Wo=a(", which is like "),Vl=o("code"),Jl=a("Adam"),Go=a(", but with a fix in the way weight decay is applied:"),Mn=c(),j(Ss.$$.fragment),Hn=c(),ga=o("p"),Uo=a("Once we have all those objects, we can send them to the "),yt=o("code"),Ql=a("accelerator.prepare()"),Yo=a(" method:"),Wn=c(),j(Fs.$$.fragment),Gn=c(),j(Ra.$$.fragment),ml=c(),ds=o("p"),Xo=a("Now that we have sent our "),en=o("code"),us=a("train_dataloader"),tn=a(" to "),sn=o("code"),Zo=a("accelerator.prepare()"),an=a(", we can use its length to compute the number of training steps. Remember that we should always do this after preparing the dataloader, as that method will change its length. We use a classic linear schedule from the learning rate to 0:"),Un=c(),j(Ba.$$.fragment),_l=c(),jt=o("p"),Ko=a("Lastly, to push our model to the Hub, we will need to create a "),bl=o("code"),wl=a("Repository"),Vo=a(" object in a working folder. First log in to Hugging Face, if you\u2019re not logged in already. We\u2019ll determine the repository name from the model ID we want to give our model (feel free to replace the "),gl=o("code"),Ma=a("repo_name"),Yn=a(" with your own choice; it just needs to contain your username, which is what the function "),Ls=o("code"),Xn=a("get_full_repo_name()"),fs=a(" does):"),Zn=c(),j(Rs.$$.fragment),Kn=c(),j(Ha.$$.fragment),vl=c(),kl=o("p"),Jo=a("Then we can clone that repository in a local folder. If it already exists, this local folder should be an existing clone of the repository we are working with:"),ln=c(),j(Xt.$$.fragment),nn=c(),Ce=o("p"),Qo=a("We can now upload anything we save in "),Wa=o("code"),er=a("output_dir"),tr=a(" by calling the "),Ga=o("code"),sr=a("repo.push_to_hub()"),ar=a(" method. This will help us upload the intermediate models at the end of each epoch."),on=c(),at=o("h3"),Bs=o("a"),Zt=o("span"),j(Et.$$.fragment),rn=c(),Ms=o("span"),lr=a("Training loop"),$l=c(),ms=o("p"),Vn=a("We are now ready to write the full training loop. To simplify its evaluation part, we define this "),Hs=o("code"),Jn=a("postprocess()"),_s=a(" function that takes predictions and labels and converts them to lists of strings, like our "),pn=o("code"),yl=a("metric"),nr=a(" object expects:"),Qn=c(),j(Ws.$$.fragment),eo=c(),jl=o("p"),to=a("Then we can write the training loop. After defining a progress bar to follow how training goes, the loop has three parts:"),Gs=c(),bs=o("ul"),Us=o("li"),or=a("The training in itself, which is the classic iteration over the "),cn=o("code"),so=a("train_dataloader"),Ua=a(", forward pass through the model, then backward pass and optimizer step."),ao=c(),ae=o("li"),rr=a("The evaluation, in which there is a novelty after getting the outputs of our model on a batch: since two processes may have padded the inputs and labels to different shapes, we need to use "),Ya=o("code"),ir=a("accelerator.pad_across_processes()"),pr=a(" to make the predictions and labels the same shape before calling the "),Ys=o("code"),cr=a("gather()"),hr=a(" method. If we don\u2019t do this, the evaluation will either error out or hang forever. Then we send the results to "),Xs=o("code"),dr=a("metric.add_batch()"),ur=a(" and call "),Xa=o("code"),fr=a("metric.compute()"),mr=a(" once the evaluation loop is over."),hn=c(),Zs=o("li"),_r=a("Saving and uploading, where we first save the model and the tokenizer, then call "),El=o("code"),Za=a("repo.push_to_hub()"),lo=a(". Notice that we use the argument "),Ks=o("code"),no=a("blocking=False"),ws=a(" to tell the \u{1F917} Hub library to push in an asynchronous process. This way, training continues normally and this (long) instruction is executed in the background."),oo=c(),va=o("p"),br=a("Here\u2019s the complete code for the training loop:"),ro=c(),j(Vs.$$.fragment),io=c(),xl=o("p"),po=a("In case this is the first time you\u2019re seeing a model saved with \u{1F917} Accelerate, let\u2019s take a moment to inspect the three lines of code that go with it:"),ka=c(),j($a.$$.fragment),ya=c(),he=o("p"),Ne=a("The first line is self-explanatory: it tells all the processes to wait until everyone is at that stage before continuing. This is to make sure we have the same model in every process before saving. Then we grab the "),dn=o("code"),un=a("unwrapped_model"),wr=a(", which is the base model we defined. The "),fn=o("code"),mn=a("accelerator.prepare()"),gr=a(" method changes the model to work in distributed training, so it won\u2019t have the "),_n=o("code"),bn=a("save_pretrained()"),vr=a(" method anymore; the "),wn=o("code"),gn=a("accelerator.unwrap_model()"),kr=a(" method undoes that step. Lastly, we call "),vn=o("code"),kn=a("save_pretrained()"),$r=a(" but tell that method to use "),$n=o("code"),co=a("accelerator.save()"),ja=a(" instead of "),yn=o("code"),Ol=a("torch.save()"),yr=a("."),ho=c(),Kt=o("p"),Ka=a("Once this is done, you should have a model that produces results pretty similar to the one trained with the "),Cl=o("code"),Va=a("Trainer"),uo=a(". You can check the model we trained using this code at "),$e=o("a"),jn=o("em"),En=a("huggingface-course/bert-finetuned-ner-accelerate"),jr=a(". And if you want to test out any tweaks to the training loop, you can directly implement them by editing the code shown above!"),this.h()},l(n){d=r(n,"H3",{class:!0});var _=i(d);g=r(_,"A",{id:!0,class:!0,href:!0});var ii=i(g);m=r(ii,"SPAN",{});var mo=i(m);E($.$$.fragment,mo),mo.forEach(s),ii.forEach(s),T=h(_),v=r(_,"SPAN",{});var pi=i(v);y=l(pi,"Defining the model"),pi.forEach(s),_.forEach(s),D=h(n),z=r(n,"P",{});var Tl=i(z);N=l(Tl,"Since we are working on a token classification problem, we will use the "),B=r(Tl,"CODE",{});var _o=i(B);A=l(_o,"AutoModelForTokenClassification"),_o.forEach(s),I=l(Tl," class. The main thing to remember when defining this model is to pass along some information on the number of labels we have. The easiest way to do this is to pass that number with the "),M=r(Tl,"CODE",{});var ci=i(M);G=l(ci,"num_labels"),ci.forEach(s),Z=l(Tl," argument, but if we want a nice inference widget working like the one we saw at the beginning of this section, it\u2019s better to set the correct label correspondences instead."),Tl.forEach(s),X=h(n),C=r(n,"P",{});var Dl=i(C);S=l(Dl,"They should be set by two dictionaries, "),P=r(Dl,"CODE",{});var Er=i(P);H=l(Er,"id2label"),Er.forEach(s),F=l(Dl," and "),Y=r(Dl,"CODE",{});var Pl=i(Y);Q=l(Pl,"label2id"),Pl.forEach(s),ee=l(Dl,", which contain the mappings from ID to label and vice versa:"),Dl.forEach(s),oe=h(n),E(K.$$.fragment,n),de=h(n),J=r(n,"P",{});var xn=i(J);W=l(xn,"Now we can just pass them to the "),R=r(xn,"CODE",{});var On=i(R);le=l(On,"AutoModelForTokenClassification.from_pretrained()"),On.forEach(s),ue=l(xn," method, and they will be set in the model\u2019s configuration and then properly saved and uploaded to the Hub:"),xn.forEach(s),ye=h(n),E(ne.$$.fragment,n),Fe=h(n),V=r(n,"P",{});var zl=i(V);nt=l(zl,"Like when we defined our "),pe=r(zl,"CODE",{});var xr=i(pe);dt=l(xr,"AutoModelForSequenceClassification"),xr.forEach(s),Qt=l(zl," in "),ot=r(zl,"A",{href:!0});var ql=i(ot);ea=l(ql,"Chapter 3"),ql.forEach(s),Tt=l(zl,", creating the model issues a warning that some weights were not used (the ones from the pretraining head) and some other weights are randomly initialized (the ones from the new token classification head), and that this model should be trained. We will do that in a minute, but first let\u2019s double-check that our model has the right number of labels:"),zl.forEach(s),es=h(n),E(we.$$.fragment,n),Es=h(n),E(Te.$$.fragment,n),fe=h(n),E(Ye.$$.fragment,n),ts=h(n),se=r(n,"H3",{class:!0});var Cn=i(se);ce=r(Cn,"A",{id:!0,class:!0,href:!0});var Al=i(ce);ss=r(Al,"SPAN",{});var Or=i(ss);E(Le.$$.fragment,Or),Or.forEach(s),Al.forEach(s),Dt=h(Cn),as=r(Cn,"SPAN",{});var Js=i(as);ta=l(Js,"Fine-tuning the model"),Js.forEach(s),Cn.forEach(s),Xe=h(n),Re=r(n,"P",{});var bo=i(Re);Pt=l(bo,"We are now ready to train our model! We just need to do two last things before we define our "),ls=r(bo,"CODE",{});var wo=i(ls);zt=l(wo,"Trainer"),wo.forEach(s),xs=l(bo,": log in to Hugging Face and define our training arguments. If you\u2019re working in a notebook, there\u2019s a convenience function to help you with this:"),bo.forEach(s),je=h(n),E(De.$$.fragment,n),qt=h(n),Ee=r(n,"P",{});var hi=i(Ee);Da=l(hi,"This will display a widget where you can enter your Hugging Face login credentials."),hi.forEach(s),At=h(n),Ze=r(n,"P",{});var di=i(Ze);Os=l(di,"If you aren\u2019t working in a notebook, just type the following line in your terminal:"),di.forEach(s),ie=h(n),E(It.$$.fragment,n),Ke=h(n),ut=r(n,"P",{});var Il=i(ut);Pa=l(Il,"Once this is done, we can define our "),ft=r(Il,"CODE",{});var ui=i(ft);mt=l(ui,"TrainingArguments"),ui.forEach(s),sa=l(Il,":"),Il.forEach(s),Pe=h(n),E(ze.$$.fragment,n),ns=h(n),te=r(n,"P",{});var lt=i(te);Nt=l(lt,"You\u2019ve seen most of those before: we set some hyperparameters (like the learning rate, the number of epochs to train for, and the weight decay), and we specify "),_t=r(lt,"CODE",{});var Cr=i(_t);Ve=l(Cr,"push_to_hub=True"),Cr.forEach(s),aa=l(lt," to indicate that we want to save the model and evaluate it at the end of every epoch, and that we want to upload our results to the Model Hub. Note that you can specify the name of the repository you want to push to with the "),qe=r(lt,"CODE",{});var Ja=i(qe);za=l(Ja,"hub_model_id"),Ja.forEach(s),Cs=l(lt," argument (in particular, you will have to use this argument to push to an organization). For instance, when we pushed the model to the "),Je=r(lt,"A",{href:!0,rel:!0});var go=i(Je);Ts=r(go,"CODE",{});var ht=i(Ts);la=l(ht,"huggingface-course"),ht.forEach(s),bt=l(go," organization"),go.forEach(s),rt=l(lt,", we added "),Qe=r(lt,"CODE",{});var fi=i(Qe);Ds=l(fi,'hub_model_id="huggingface-course/bert-finetuned-ner"'),fi.forEach(s),os=l(lt," to "),Ps=r(lt,"CODE",{});var vo=i(Ps);na=l(vo,"TrainingArguments"),vo.forEach(s),wt=l(lt,". By default, the repository used will be in your namespace and named after the output directory you set, so in our case it will be "),et=r(lt,"CODE",{});var mi=i(et);me=l(mi,'"sgugger/bert-finetuned-ner"'),mi.forEach(s),St=l(lt,"."),lt.forEach(s),Ft=h(n),E(Ae.$$.fragment,n),oa=h(n),_e=r(n,"P",{});var ko=i(_e);zs=l(ko,"Finally, we just pass everything to the "),qs=r(ko,"CODE",{});var $o=i(qs);ra=l($o,"Trainer"),$o.forEach(s),rs=l(ko," and launch the training:"),ko.forEach(s),is=h(n),E(gt.$$.fragment,n),vt=h(n),it=r(n,"P",{});var _i=i(it);Lt=l(_i,"Note that while the training happens, each time the model is saved (here, every epoch) it is uploaded to the Hub in the background. This way, you will be able to to resume your training on another machine if necessary."),_i.forEach(s),As=h(n),Ie=r(n,"P",{});var yo=i(Ie);Rt=l(yo,"Once the training is complete, we use the "),Bt=r(yo,"CODE",{});var jo=i(Bt);tt=l(jo,"push_to_hub()"),jo.forEach(s),ia=l(yo," method to make sure we upload the most recent version of the model:"),yo.forEach(s),pt=h(n),E(Be.$$.fragment,n),ct=h(n),Mt=r(n,"P",{});var bi=i(Mt);f=l(bi,"This command returns the URL of the commit it just did, if you want to inspect it:"),bi.forEach(s),L=h(n),E(ps.$$.fragment,n),pa=h(n),Me=r(n,"P",{});var Eo=i(Me);Ht=l(Eo,"The "),kt=r(Eo,"CODE",{});var xo=i(kt);qa=l(xo,"Trainer"),xo.forEach(s),re=l(Eo," also drafts a model card with all the evaluation results and uploads it. At this stage, you can use the inference widget on the Model Hub to test your model and share it with your friends. You have successfully fine-tuned a model on a token classification task \u2014 congratulations!"),Eo.forEach(s),Aa=h(n),Wt=r(n,"P",{});var wi=i(Wt);ca=l(wi,"If you want to dive a bit more deeply into the training loop, we will now show you how to do the same thing using \u{1F917} Accelerate."),wi.forEach(s),Ia=h(n),ge=r(n,"H2",{class:!0});var Oo=i(ge);Gt=r(Oo,"A",{id:!0,class:!0,href:!0});var Tr=i(Gt);ha=r(Tr,"SPAN",{});var Nl=i(ha);E(st.$$.fragment,Nl),Nl.forEach(s),Tr.forEach(s),pl=h(Oo),da=r(Oo,"SPAN",{});var Dr=i(da);ua=l(Dr,"A custom training loop"),Dr.forEach(s),Oo.forEach(s),Na=h(n),Ut=r(n,"P",{});var Qa=i(Ut);fa=l(Qa,"Let\u2019s now take a look at the full training loop, so you can easily customize the parts you need. It will look a lot like what we did in "),He=r(Qa,"A",{href:!0});var gi=i(He);cl=l(gi,"Chapter 3"),gi.forEach(s),Sa=l(Qa,", with a few changes for the evaluation."),Qa.forEach(s),Yt=h(n),xe=r(n,"H3",{class:!0});var Tn=i(xe);We=r(Tn,"A",{id:!0,class:!0,href:!0});var Dn=i(We);Is=r(Dn,"SPAN",{});var vi=i(Is);E(be.$$.fragment,vi),vi.forEach(s),Dn.forEach(s),hl=h(Tn),ve=r(Tn,"SPAN",{});var Pr=i(ve);dl=l(Pr,"Preparing everything for training"),Pr.forEach(s),Tn.forEach(s),ma=h(n),ke=r(n,"P",{});var xt=i(ke);ul=l(xt,"First we need to build the "),_a=r(xt,"CODE",{});var zr=i(_a);Fa=l(zr,"DataLoader"),zr.forEach(s),Oe=l(xt,"s from our datasets. We\u2019ll reuse our "),ba=r(xt,"CODE",{});var el=i(ba);Xl=l(el,"data_collator"),el.forEach(s),Ro=l(xt," as a "),Zl=r(xt,"CODE",{});var ki=i(Zl);Bo=l(ki,"collate_fn"),ki.forEach(s),cs=l(xt," and shuffle the training set, but not the validation set:"),xt.forEach(s),fl=h(n),E(La.$$.fragment,n),Ln=h(n),wa=r(n,"P",{});var Pn=i(wa);Mo=l(Pn,"Next we reinstantiate our model, to make sure we\u2019re not continuing the fine-tuning from before but starting from the BERT pretrained model again:"),Pn.forEach(s),Rn=h(n),E(Ns.$$.fragment,n),Bn=h(n),hs=r(n,"P",{});var Sl=i(hs);Ho=l(Sl,"Then we will need an optimizer. We\u2019ll use the classic "),$t=r(Sl,"CODE",{});var $i=i($t);Kl=l($i,"AdamW"),$i.forEach(s),Wo=l(Sl,", which is like "),Vl=r(Sl,"CODE",{});var qr=i(Vl);Jl=l(qr,"Adam"),qr.forEach(s),Go=l(Sl,", but with a fix in the way weight decay is applied:"),Sl.forEach(s),Mn=h(n),E(Ss.$$.fragment,n),Hn=h(n),ga=r(n,"P",{});var Ot=i(ga);Uo=l(Ot,"Once we have all those objects, we can send them to the "),yt=r(Ot,"CODE",{});var gs=i(yt);Ql=l(gs,"accelerator.prepare()"),gs.forEach(s),Yo=l(Ot," method:"),Ot.forEach(s),Wn=h(n),E(Fs.$$.fragment,n),Gn=h(n),E(Ra.$$.fragment,n),ml=h(n),ds=r(n,"P",{});var Qs=i(ds);Xo=l(Qs,"Now that we have sent our "),en=r(Qs,"CODE",{});var Ea=i(en);us=l(Ea,"train_dataloader"),Ea.forEach(s),tn=l(Qs," to "),sn=r(Qs,"CODE",{});var tl=i(sn);Zo=l(tl,"accelerator.prepare()"),tl.forEach(s),an=l(Qs,", we can use its length to compute the number of training steps. Remember that we should always do this after preparing the dataloader, as that method will change its length. We use a classic linear schedule from the learning rate to 0:"),Qs.forEach(s),Un=h(n),E(Ba.$$.fragment,n),_l=h(n),jt=r(n,"P",{});var vs=i(jt);Ko=l(vs,"Lastly, to push our model to the Hub, we will need to create a "),bl=r(vs,"CODE",{});var Fl=i(bl);wl=l(Fl,"Repository"),Fl.forEach(s),Vo=l(vs," object in a working folder. First log in to Hugging Face, if you\u2019re not logged in already. We\u2019ll determine the repository name from the model ID we want to give our model (feel free to replace the "),gl=r(vs,"CODE",{});var yi=i(gl);Ma=l(yi,"repo_name"),yi.forEach(s),Yn=l(vs," with your own choice; it just needs to contain your username, which is what the function "),Ls=r(vs,"CODE",{});var Co=i(Ls);Xn=l(Co,"get_full_repo_name()"),Co.forEach(s),fs=l(vs," does):"),vs.forEach(s),Zn=h(n),E(Rs.$$.fragment,n),Kn=h(n),E(Ha.$$.fragment,n),vl=h(n),kl=r(n,"P",{});var ji=i(kl);Jo=l(ji,"Then we can clone that repository in a local folder. If it already exists, this local folder should be an existing clone of the repository we are working with:"),ji.forEach(s),ln=h(n),E(Xt.$$.fragment,n),nn=h(n),Ce=r(n,"P",{});var sl=i(Ce);Qo=l(sl,"We can now upload anything we save in "),Wa=r(sl,"CODE",{});var Vt=i(Wa);er=l(Vt,"output_dir"),Vt.forEach(s),tr=l(sl," by calling the "),Ga=r(sl,"CODE",{});var Ei=i(Ga);sr=l(Ei,"repo.push_to_hub()"),Ei.forEach(s),ar=l(sl," method. This will help us upload the intermediate models at the end of each epoch."),sl.forEach(s),on=h(n),at=r(n,"H3",{class:!0});var Ll=i(at);Bs=r(Ll,"A",{id:!0,class:!0,href:!0});var xi=i(Bs);Zt=r(xi,"SPAN",{});var Oi=i(Zt);E(Et.$$.fragment,Oi),Oi.forEach(s),xi.forEach(s),rn=h(Ll),Ms=r(Ll,"SPAN",{});var zn=i(Ms);lr=l(zn,"Training loop"),zn.forEach(s),Ll.forEach(s),$l=h(n),ms=r(n,"P",{});var Rl=i(ms);Vn=l(Rl,"We are now ready to write the full training loop. To simplify its evaluation part, we define this "),Hs=r(Rl,"CODE",{});var Ci=i(Hs);Jn=l(Ci,"postprocess()"),Ci.forEach(s),_s=l(Rl," function that takes predictions and labels and converts them to lists of strings, like our "),pn=r(Rl,"CODE",{});var To=i(pn);yl=l(To,"metric"),To.forEach(s),nr=l(Rl," object expects:"),Rl.forEach(s),Qn=h(n),E(Ws.$$.fragment,n),eo=h(n),jl=r(n,"P",{});var Ti=i(jl);to=l(Ti,"Then we can write the training loop. After defining a progress bar to follow how training goes, the loop has three parts:"),Ti.forEach(s),Gs=h(n),bs=r(n,"UL",{});var Bl=i(bs);Us=r(Bl,"LI",{});var qn=i(Us);or=l(qn,"The training in itself, which is the classic iteration over the "),cn=r(qn,"CODE",{});var Jt=i(cn);so=l(Jt,"train_dataloader"),Jt.forEach(s),Ua=l(qn,", forward pass through the model, then backward pass and optimizer step."),qn.forEach(s),ao=h(Bl),ae=r(Bl,"LI",{});var ks=i(ae);rr=l(ks,"The evaluation, in which there is a novelty after getting the outputs of our model on a batch: since two processes may have padded the inputs and labels to different shapes, we need to use "),Ya=r(ks,"CODE",{});var Ml=i(Ya);ir=l(Ml,"accelerator.pad_across_processes()"),Ml.forEach(s),pr=l(ks," to make the predictions and labels the same shape before calling the "),Ys=r(ks,"CODE",{});var Do=i(Ys);cr=l(Do,"gather()"),Do.forEach(s),hr=l(ks," method. If we don\u2019t do this, the evaluation will either error out or hang forever. Then we send the results to "),Xs=r(ks,"CODE",{});var Di=i(Xs);dr=l(Di,"metric.add_batch()"),Di.forEach(s),ur=l(ks," and call "),Xa=r(ks,"CODE",{});var Pi=i(Xa);fr=l(Pi,"metric.compute()"),Pi.forEach(s),mr=l(ks," once the evaluation loop is over."),ks.forEach(s),hn=h(Bl),Zs=r(Bl,"LI",{});var xa=i(Zs);_r=l(xa,"Saving and uploading, where we first save the model and the tokenizer, then call "),El=r(xa,"CODE",{});var zi=i(El);Za=l(zi,"repo.push_to_hub()"),zi.forEach(s),lo=l(xa,". Notice that we use the argument "),Ks=r(xa,"CODE",{});var qi=i(Ks);no=l(qi,"blocking=False"),qi.forEach(s),ws=l(xa," to tell the \u{1F917} Hub library to push in an asynchronous process. This way, training continues normally and this (long) instruction is executed in the background."),xa.forEach(s),Bl.forEach(s),oo=h(n),va=r(n,"P",{});var Po=i(va);br=l(Po,"Here\u2019s the complete code for the training loop:"),Po.forEach(s),ro=h(n),E(Vs.$$.fragment,n),io=h(n),xl=r(n,"P",{});var Ai=i(xl);po=l(Ai,"In case this is the first time you\u2019re seeing a model saved with \u{1F917} Accelerate, let\u2019s take a moment to inspect the three lines of code that go with it:"),Ai.forEach(s),ka=h(n),E($a.$$.fragment,n),ya=h(n),he=r(n,"P",{});var Se=i(he);Ne=l(Se,"The first line is self-explanatory: it tells all the processes to wait until everyone is at that stage before continuing. This is to make sure we have the same model in every process before saving. Then we grab the "),dn=r(Se,"CODE",{});var Ar=i(dn);un=l(Ar,"unwrapped_model"),Ar.forEach(s),wr=l(Se,", which is the base model we defined. The "),fn=r(Se,"CODE",{});var $s=i(fn);mn=l($s,"accelerator.prepare()"),$s.forEach(s),gr=l(Se," method changes the model to work in distributed training, so it won\u2019t have the "),_n=r(Se,"CODE",{});var ys=i(_n);bn=l(ys,"save_pretrained()"),ys.forEach(s),vr=l(Se," method anymore; the "),wn=r(Se,"CODE",{});var An=i(wn);gn=l(An,"accelerator.unwrap_model()"),An.forEach(s),kr=l(Se," method undoes that step. Lastly, we call "),vn=r(Se,"CODE",{});var In=i(vn);kn=l(In,"save_pretrained()"),In.forEach(s),$r=l(Se," but tell that method to use "),$n=r(Se,"CODE",{});var Ii=i($n);co=l(Ii,"accelerator.save()"),Ii.forEach(s),ja=l(Se," instead of "),yn=r(Se,"CODE",{});var Ir=i(yn);Ol=l(Ir,"torch.save()"),Ir.forEach(s),yr=l(Se,"."),Se.forEach(s),ho=h(n),Kt=r(n,"P",{});var js=i(Kt);Ka=l(js,"Once this is done, you should have a model that produces results pretty similar to the one trained with the "),Cl=r(js,"CODE",{});var Nr=i(Cl);Va=l(Nr,"Trainer"),Nr.forEach(s),uo=l(js,". You can check the model we trained using this code at "),$e=r(js,"A",{href:!0,rel:!0});var Hl=i($e);jn=r(Hl,"EM",{});var Sr=i(jn);En=l(Sr,"huggingface-course/bert-finetuned-ner-accelerate"),Sr.forEach(s),Hl.forEach(s),jr=l(js,". And if you want to test out any tweaks to the training loop, you can directly implement them by editing the code shown above!"),js.forEach(s),this.h()},h(){k(g,"id","defining-the-model"),k(g,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(g,"href","#defining-the-model"),k(d,"class","relative group"),k(ot,"href","/course/chapter3"),k(ce,"id","finetuning-the-model"),k(ce,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(ce,"href","#finetuning-the-model"),k(se,"class","relative group"),k(Je,"href","https://huggingface.co/huggingface-course"),k(Je,"rel","nofollow"),k(Gt,"id","a-custom-training-loop"),k(Gt,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(Gt,"href","#a-custom-training-loop"),k(ge,"class","relative group"),k(He,"href","/course/chapter3/4"),k(We,"id","preparing-everything-for-training"),k(We,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(We,"href","#preparing-everything-for-training"),k(xe,"class","relative group"),k(Bs,"id","training-loop"),k(Bs,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(Bs,"href","#training-loop"),k(at,"class","relative group"),k($e,"href","https://huggingface.co/huggingface-course/bert-finetuned-ner-accelerate"),k($e,"rel","nofollow")},m(n,_){p(n,d,_),t(d,g),t(g,m),x($,m,null),t(d,T),t(d,v),t(v,y),p(n,D,_),p(n,z,_),t(z,N),t(z,B),t(B,A),t(z,I),t(z,M),t(M,G),t(z,Z),p(n,X,_),p(n,C,_),t(C,S),t(C,P),t(P,H),t(C,F),t(C,Y),t(Y,Q),t(C,ee),p(n,oe,_),x(K,n,_),p(n,de,_),p(n,J,_),t(J,W),t(J,R),t(R,le),t(J,ue),p(n,ye,_),x(ne,n,_),p(n,Fe,_),p(n,V,_),t(V,nt),t(V,pe),t(pe,dt),t(V,Qt),t(V,ot),t(ot,ea),t(V,Tt),p(n,es,_),x(we,n,_),p(n,Es,_),x(Te,n,_),p(n,fe,_),x(Ye,n,_),p(n,ts,_),p(n,se,_),t(se,ce),t(ce,ss),x(Le,ss,null),t(se,Dt),t(se,as),t(as,ta),p(n,Xe,_),p(n,Re,_),t(Re,Pt),t(Re,ls),t(ls,zt),t(Re,xs),p(n,je,_),x(De,n,_),p(n,qt,_),p(n,Ee,_),t(Ee,Da),p(n,At,_),p(n,Ze,_),t(Ze,Os),p(n,ie,_),x(It,n,_),p(n,Ke,_),p(n,ut,_),t(ut,Pa),t(ut,ft),t(ft,mt),t(ut,sa),p(n,Pe,_),x(ze,n,_),p(n,ns,_),p(n,te,_),t(te,Nt),t(te,_t),t(_t,Ve),t(te,aa),t(te,qe),t(qe,za),t(te,Cs),t(te,Je),t(Je,Ts),t(Ts,la),t(Je,bt),t(te,rt),t(te,Qe),t(Qe,Ds),t(te,os),t(te,Ps),t(Ps,na),t(te,wt),t(te,et),t(et,me),t(te,St),p(n,Ft,_),x(Ae,n,_),p(n,oa,_),p(n,_e,_),t(_e,zs),t(_e,qs),t(qs,ra),t(_e,rs),p(n,is,_),x(gt,n,_),p(n,vt,_),p(n,it,_),t(it,Lt),p(n,As,_),p(n,Ie,_),t(Ie,Rt),t(Ie,Bt),t(Bt,tt),t(Ie,ia),p(n,pt,_),x(Be,n,_),p(n,ct,_),p(n,Mt,_),t(Mt,f),p(n,L,_),x(ps,n,_),p(n,pa,_),p(n,Me,_),t(Me,Ht),t(Me,kt),t(kt,qa),t(Me,re),p(n,Aa,_),p(n,Wt,_),t(Wt,ca),p(n,Ia,_),p(n,ge,_),t(ge,Gt),t(Gt,ha),x(st,ha,null),t(ge,pl),t(ge,da),t(da,ua),p(n,Na,_),p(n,Ut,_),t(Ut,fa),t(Ut,He),t(He,cl),t(Ut,Sa),p(n,Yt,_),p(n,xe,_),t(xe,We),t(We,Is),x(be,Is,null),t(xe,hl),t(xe,ve),t(ve,dl),p(n,ma,_),p(n,ke,_),t(ke,ul),t(ke,_a),t(_a,Fa),t(ke,Oe),t(ke,ba),t(ba,Xl),t(ke,Ro),t(ke,Zl),t(Zl,Bo),t(ke,cs),p(n,fl,_),x(La,n,_),p(n,Ln,_),p(n,wa,_),t(wa,Mo),p(n,Rn,_),x(Ns,n,_),p(n,Bn,_),p(n,hs,_),t(hs,Ho),t(hs,$t),t($t,Kl),t(hs,Wo),t(hs,Vl),t(Vl,Jl),t(hs,Go),p(n,Mn,_),x(Ss,n,_),p(n,Hn,_),p(n,ga,_),t(ga,Uo),t(ga,yt),t(yt,Ql),t(ga,Yo),p(n,Wn,_),x(Fs,n,_),p(n,Gn,_),x(Ra,n,_),p(n,ml,_),p(n,ds,_),t(ds,Xo),t(ds,en),t(en,us),t(ds,tn),t(ds,sn),t(sn,Zo),t(ds,an),p(n,Un,_),x(Ba,n,_),p(n,_l,_),p(n,jt,_),t(jt,Ko),t(jt,bl),t(bl,wl),t(jt,Vo),t(jt,gl),t(gl,Ma),t(jt,Yn),t(jt,Ls),t(Ls,Xn),t(jt,fs),p(n,Zn,_),x(Rs,n,_),p(n,Kn,_),x(Ha,n,_),p(n,vl,_),p(n,kl,_),t(kl,Jo),p(n,ln,_),x(Xt,n,_),p(n,nn,_),p(n,Ce,_),t(Ce,Qo),t(Ce,Wa),t(Wa,er),t(Ce,tr),t(Ce,Ga),t(Ga,sr),t(Ce,ar),p(n,on,_),p(n,at,_),t(at,Bs),t(Bs,Zt),x(Et,Zt,null),t(at,rn),t(at,Ms),t(Ms,lr),p(n,$l,_),p(n,ms,_),t(ms,Vn),t(ms,Hs),t(Hs,Jn),t(ms,_s),t(ms,pn),t(pn,yl),t(ms,nr),p(n,Qn,_),x(Ws,n,_),p(n,eo,_),p(n,jl,_),t(jl,to),p(n,Gs,_),p(n,bs,_),t(bs,Us),t(Us,or),t(Us,cn),t(cn,so),t(Us,Ua),t(bs,ao),t(bs,ae),t(ae,rr),t(ae,Ya),t(Ya,ir),t(ae,pr),t(ae,Ys),t(Ys,cr),t(ae,hr),t(ae,Xs),t(Xs,dr),t(ae,ur),t(ae,Xa),t(Xa,fr),t(ae,mr),t(bs,hn),t(bs,Zs),t(Zs,_r),t(Zs,El),t(El,Za),t(Zs,lo),t(Zs,Ks),t(Ks,no),t(Zs,ws),p(n,oo,_),p(n,va,_),t(va,br),p(n,ro,_),x(Vs,n,_),p(n,io,_),p(n,xl,_),t(xl,po),p(n,ka,_),x($a,n,_),p(n,ya,_),p(n,he,_),t(he,Ne),t(he,dn),t(dn,un),t(he,wr),t(he,fn),t(fn,mn),t(he,gr),t(he,_n),t(_n,bn),t(he,vr),t(he,wn),t(wn,gn),t(he,kr),t(he,vn),t(vn,kn),t(he,$r),t(he,$n),t($n,co),t(he,ja),t(he,yn),t(yn,Ol),t(he,yr),p(n,ho,_),p(n,Kt,_),t(Kt,Ka),t(Kt,Cl),t(Cl,Va),t(Kt,uo),t(Kt,$e),t($e,jn),t(jn,En),t(Kt,jr),fo=!0},i(n){fo||(b($.$$.fragment,n),b(K.$$.fragment,n),b(ne.$$.fragment,n),b(we.$$.fragment,n),b(Te.$$.fragment,n),b(Ye.$$.fragment,n),b(Le.$$.fragment,n),b(De.$$.fragment,n),b(It.$$.fragment,n),b(ze.$$.fragment,n),b(Ae.$$.fragment,n),b(gt.$$.fragment,n),b(Be.$$.fragment,n),b(ps.$$.fragment,n),b(st.$$.fragment,n),b(be.$$.fragment,n),b(La.$$.fragment,n),b(Ns.$$.fragment,n),b(Ss.$$.fragment,n),b(Fs.$$.fragment,n),b(Ra.$$.fragment,n),b(Ba.$$.fragment,n),b(Rs.$$.fragment,n),b(Ha.$$.fragment,n),b(Xt.$$.fragment,n),b(Et.$$.fragment,n),b(Ws.$$.fragment,n),b(Vs.$$.fragment,n),b($a.$$.fragment,n),fo=!0)},o(n){w($.$$.fragment,n),w(K.$$.fragment,n),w(ne.$$.fragment,n),w(we.$$.fragment,n),w(Te.$$.fragment,n),w(Ye.$$.fragment,n),w(Le.$$.fragment,n),w(De.$$.fragment,n),w(It.$$.fragment,n),w(ze.$$.fragment,n),w(Ae.$$.fragment,n),w(gt.$$.fragment,n),w(Be.$$.fragment,n),w(ps.$$.fragment,n),w(st.$$.fragment,n),w(be.$$.fragment,n),w(La.$$.fragment,n),w(Ns.$$.fragment,n),w(Ss.$$.fragment,n),w(Fs.$$.fragment,n),w(Ra.$$.fragment,n),w(Ba.$$.fragment,n),w(Rs.$$.fragment,n),w(Ha.$$.fragment,n),w(Xt.$$.fragment,n),w(Et.$$.fragment,n),w(Ws.$$.fragment,n),w(Vs.$$.fragment,n),w($a.$$.fragment,n),fo=!1},d(n){n&&s(d),O($),n&&s(D),n&&s(z),n&&s(X),n&&s(C),n&&s(oe),O(K,n),n&&s(de),n&&s(J),n&&s(ye),O(ne,n),n&&s(Fe),n&&s(V),n&&s(es),O(we,n),n&&s(Es),O(Te,n),n&&s(fe),O(Ye,n),n&&s(ts),n&&s(se),O(Le),n&&s(Xe),n&&s(Re),n&&s(je),O(De,n),n&&s(qt),n&&s(Ee),n&&s(At),n&&s(Ze),n&&s(ie),O(It,n),n&&s(Ke),n&&s(ut),n&&s(Pe),O(ze,n),n&&s(ns),n&&s(te),n&&s(Ft),O(Ae,n),n&&s(oa),n&&s(_e),n&&s(is),O(gt,n),n&&s(vt),n&&s(it),n&&s(As),n&&s(Ie),n&&s(pt),O(Be,n),n&&s(ct),n&&s(Mt),n&&s(L),O(ps,n),n&&s(pa),n&&s(Me),n&&s(Aa),n&&s(Wt),n&&s(Ia),n&&s(ge),O(st),n&&s(Na),n&&s(Ut),n&&s(Yt),n&&s(xe),O(be),n&&s(ma),n&&s(ke),n&&s(fl),O(La,n),n&&s(Ln),n&&s(wa),n&&s(Rn),O(Ns,n),n&&s(Bn),n&&s(hs),n&&s(Mn),O(Ss,n),n&&s(Hn),n&&s(ga),n&&s(Wn),O(Fs,n),n&&s(Gn),O(Ra,n),n&&s(ml),n&&s(ds),n&&s(Un),O(Ba,n),n&&s(_l),n&&s(jt),n&&s(Zn),O(Rs,n),n&&s(Kn),O(Ha,n),n&&s(vl),n&&s(kl),n&&s(ln),O(Xt,n),n&&s(nn),n&&s(Ce),n&&s(on),n&&s(at),O(Et),n&&s($l),n&&s(ms),n&&s(Qn),O(Ws,n),n&&s(eo),n&&s(jl),n&&s(Gs),n&&s(bs),n&&s(oo),n&&s(va),n&&s(ro),O(Vs,n),n&&s(io),n&&s(xl),n&&s(ka),O($a,n),n&&s(ya),n&&s(he),n&&s(ho),n&&s(Kt)}}}function Id(U){let d,g,m,$,T;return{c(){d=o("p"),g=a("\u26A0\uFE0F If you have a model with the wrong number of labels, you will get an obscure error when calling the "),m=o("code"),$=a("Trainer.train()"),T=a(" method later on (something like \u201CCUDA error: device-side assert triggered\u201D). This is the number one cause of bugs reported by users for such errors, so make sure you do this check to confirm that you have the expected number of labels.")},l(v){d=r(v,"P",{});var y=i(d);g=l(y,"\u26A0\uFE0F If you have a model with the wrong number of labels, you will get an obscure error when calling the "),m=r(y,"CODE",{});var D=i(m);$=l(D,"Trainer.train()"),D.forEach(s),T=l(y," method later on (something like \u201CCUDA error: device-side assert triggered\u201D). This is the number one cause of bugs reported by users for such errors, so make sure you do this check to confirm that you have the expected number of labels."),y.forEach(s)},m(v,y){p(v,d,y),t(d,g),t(d,m),t(m,$),t(d,T)},d(v){v&&s(d)}}}function Nd(U){let d,g,m,$,T;return{c(){d=o("p"),g=a("\u{1F4A1} If the output directory you are using already exists, it needs to be a local clone of the repository you want to push to. If it isn\u2019t, you\u2019ll get an error when defining your "),m=o("code"),$=a("Trainer"),T=a(" and will need to set a new name.")},l(v){d=r(v,"P",{});var y=i(d);g=l(y,"\u{1F4A1} If the output directory you are using already exists, it needs to be a local clone of the repository you want to push to. If it isn\u2019t, you\u2019ll get an error when defining your "),m=r(y,"CODE",{});var D=i(m);$=l(D,"Trainer"),D.forEach(s),T=l(y," and will need to set a new name."),y.forEach(s)},m(v,y){p(v,d,y),t(d,g),t(d,m),t(m,$),t(d,T)},d(v){v&&s(d)}}}function Sd(U){let d,g,m,$,T;return{c(){d=o("p"),g=a("\u{1F6A8} If you\u2019re training on a TPU, you\u2019ll need to move all the code starting from the cell above into a dedicated training function. See "),m=o("a"),$=a("Chapter 3"),T=a(" for more details."),this.h()},l(v){d=r(v,"P",{});var y=i(d);g=l(y,"\u{1F6A8} If you\u2019re training on a TPU, you\u2019ll need to move all the code starting from the cell above into a dedicated training function. See "),m=r(y,"A",{href:!0});var D=i(m);$=l(D,"Chapter 3"),D.forEach(s),T=l(y," for more details."),y.forEach(s),this.h()},h(){k(m,"href","/course/chapter3")},m(v,y){p(v,d,y),t(d,g),t(d,m),t(m,$),t(d,T)},d(v){v&&s(d)}}}function Fd(U){let d,g,m,$,T,v,y,D,z,N,B,A,I,M,G,Z,X,C,S,P,H,F,Y,Q,ee,oe,K,de,J,W,R,le,ue,ye,ne,Fe,V,nt,pe,dt,Qt,ot,ea,Tt,es,we,Es,Te,fe,Ye,ts,se,ce,ss,Le,Dt,as,ta,Xe,Re,Pt,ls,zt,xs,je,De,qt,Ee,Da,At,Ze,Os,ie,It,Ke,ut,Pa,ft,mt,sa,Pe,ze,ns,te,Nt,_t,Ve,aa,qe,za,Cs,Je,Ts,la,bt,rt,Qe,Ds,os,Ps,na,wt,et,me,St,Ft,Ae,oa,_e,zs,qs,ra,rs,is,gt,vt,it,Lt,As,Ie,Rt,Bt,tt,ia,pt,Be,ct,Mt,f,L,ps,pa,Me,Ht,kt,qa,re,Aa,Wt,ca,Ia,ge,Gt,ha,st,pl,da,ua,Na,Ut,fa,He,cl,Sa,Yt,xe,We,Is,be,hl,ve,dl,ma,ke,ul,_a,Fa,Oe,ba,Xl,Ro,Zl,Bo,cs,fl,La,Ln,wa,Mo,Rn,Ns,Bn,hs,Ho,$t,Kl,Wo,Vl,Jl,Go,Mn,Ss,Hn,ga,Uo,yt,Ql,Yo,Wn,Fs,Gn,Ra,ml,ds,Xo,en,us,tn,sn,Zo,an,Un,Ba,_l,jt,Ko,bl,wl,Vo,gl,Ma,Yn,Ls,Xn,fs,Zn,Rs,Kn,Ha,vl,kl,Jo,ln,Xt,nn,Ce,Qo,Wa,er,tr,Ga,sr,ar,on,at,Bs,Zt,Et,rn,Ms,lr,$l,ms,Vn,Hs,Jn,_s,pn,yl,nr,Qn,Ws,eo,jl,to,Gs,bs,Us,or,cn,so,Ua,ao,ae,rr,Ya,ir,pr,Ys,cr,hr,Xs,dr,ur,Xa,fr,mr,hn,Zs,_r,El,Za,lo,Ks,no,ws,oo,va,br,ro,Vs,io,xl,po,ka,$a,ya,he,Ne,dn,un,wr,fn,mn,gr,_n,bn,vr,wn,gn,kr,vn,kn,$r,$n,co,ja,yn,Ol,yr,ho,Kt,Ka,Cl,Va,uo,$e,jn,En,jr,fo,n,_,ii,mo,pi,Tl,_o,ci,Dl,Er,Pl,xn,On,zl,xr,ql,Cn,Al,Or,Js,bo,wo,hi,di,Il,ui,lt,Cr,Ja,go,ht,fi,vo,mi,ko,$o,_i,yo,jo,bi,Eo,xo,wi,Oo,Tr,Nl,Dr,Qa,gi,Tn,Dn,vi,Pr,xt,zr,el,ki,Pn,Sl,$i,qr,Ot,gs,Qs,Ea,tl,vs,Fl,yi,Co,ji,sl,Vt,Ei,Ll,xi,Oi,zn,Rl,Ci,To,Ti,Bl,qn,Jt,ks,Ml,Do,Di,Pi,xa,zi,qi,Po,Ai,Se,Ar,$s,ys,An,In,Ii,Ir,js,Nr,Hl,Sr,Ni,Hp,pp,Fr,cp,Lr,hp,al,ll,Si,Fi,Nn,zo,tp,Rr,Wp,sp,Gp,dp,nl,ol,Li,Br,up,Ri,Up,fp,Mr,mp,Hr,_p,Bi,Yp,bp,Wr,wp,Mi,Xp,gp,Gr,vp,rl,il,Hi,Wi,Sn,qo,ap,Ur,Zp,lp,Kp,kp,Ao,Vp,np,Jp,Qp,$p,Yr,yp,Xr,jp,Gi,ec,Ep;m=new bd({props:{fw:U[0]}}),D=new Ct({});const ac=[gd,wd],Zr=[];function lc(e,u){return e[0]==="pt"?0:1}I=lc(U),M=Zr[I]=ac[I](U),Tt=new id({props:{id:"wVHdVlPScxA"}}),Ee=new Ct({}),mt=new Lo({props:{$$slots:{default:[vd]},$$scope:{ctx:U}}}),te=new Ct({}),bt=new q({props:{code:`from datasets import load_dataset

raw_datasets = load_dataset("conll2003")`,highlighted:`<span class="hljs-keyword">from</span> datasets <span class="hljs-keyword">import</span> load_dataset

raw_datasets = load_dataset(<span class="hljs-string">&quot;conll2003&quot;</span>)`}}),et=new q({props:{code:"raw_datasets",highlighted:"raw_datasets"}}),St=new q({props:{code:`DatasetDict({
    train: Dataset({
        features: ['chunk_tags', 'id', 'ner_tags', 'pos_tags', 'tokens'],
        num_rows: 14041
    })
    validation: Dataset({
        features: ['chunk_tags', 'id', 'ner_tags', 'pos_tags', 'tokens'],
        num_rows: 3250
    })
    test: Dataset({
        features: ['chunk_tags', 'id', 'ner_tags', 'pos_tags', 'tokens'],
        num_rows: 3453
    })
})`,highlighted:`DatasetDict({
    train: Dataset({
        features: [<span class="hljs-string">&#x27;chunk_tags&#x27;</span>, <span class="hljs-string">&#x27;id&#x27;</span>, <span class="hljs-string">&#x27;ner_tags&#x27;</span>, <span class="hljs-string">&#x27;pos_tags&#x27;</span>, <span class="hljs-string">&#x27;tokens&#x27;</span>],
        num_rows: <span class="hljs-number">14041</span>
    })
    validation: Dataset({
        features: [<span class="hljs-string">&#x27;chunk_tags&#x27;</span>, <span class="hljs-string">&#x27;id&#x27;</span>, <span class="hljs-string">&#x27;ner_tags&#x27;</span>, <span class="hljs-string">&#x27;pos_tags&#x27;</span>, <span class="hljs-string">&#x27;tokens&#x27;</span>],
        num_rows: <span class="hljs-number">3250</span>
    })
    test: Dataset({
        features: [<span class="hljs-string">&#x27;chunk_tags&#x27;</span>, <span class="hljs-string">&#x27;id&#x27;</span>, <span class="hljs-string">&#x27;ner_tags&#x27;</span>, <span class="hljs-string">&#x27;pos_tags&#x27;</span>, <span class="hljs-string">&#x27;tokens&#x27;</span>],
        num_rows: <span class="hljs-number">3453</span>
    })
})`}}),vt=new q({props:{code:'raw_datasets["train"][0]["tokens"]',highlighted:'raw_datasets[<span class="hljs-string">&quot;train&quot;</span>][<span class="hljs-number">0</span>][<span class="hljs-string">&quot;tokens&quot;</span>]'}}),Lt=new q({props:{code:"['EU', 'rejects', 'German', 'call', 'to', 'boycott', 'British', 'lamb', '.']",highlighted:'[<span class="hljs-string">&#x27;EU&#x27;</span>, <span class="hljs-string">&#x27;rejects&#x27;</span>, <span class="hljs-string">&#x27;German&#x27;</span>, <span class="hljs-string">&#x27;call&#x27;</span>, <span class="hljs-string">&#x27;to&#x27;</span>, <span class="hljs-string">&#x27;boycott&#x27;</span>, <span class="hljs-string">&#x27;British&#x27;</span>, <span class="hljs-string">&#x27;lamb&#x27;</span>, <span class="hljs-string">&#x27;.&#x27;</span>]'}}),tt=new q({props:{code:'raw_datasets["train"][0]["ner_tags"]',highlighted:'raw_datasets[<span class="hljs-string">&quot;train&quot;</span>][<span class="hljs-number">0</span>][<span class="hljs-string">&quot;ner_tags&quot;</span>]'}}),pt=new q({props:{code:"[3, 0, 7, 0, 0, 0, 7, 0, 0]",highlighted:'[<span class="hljs-number">3</span>, <span class="hljs-number">0</span>, <span class="hljs-number">7</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">7</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>]'}}),Me=new q({props:{code:`ner_feature = raw_datasets["train"].features["ner_tags"]
ner_feature`,highlighted:`ner_feature = raw_datasets[<span class="hljs-string">&quot;train&quot;</span>].features[<span class="hljs-string">&quot;ner_tags&quot;</span>]
ner_feature`}}),kt=new q({props:{code:"Sequence(feature=ClassLabel(num_classes=9, names=['O', 'B-PER', 'I-PER', 'B-ORG', 'I-ORG', 'B-LOC', 'I-LOC', 'B-MISC', 'I-MISC'], names_file=None, id=None), length=-1, id=None)",highlighted:'<span class="hljs-type">Sequence</span>(feature=ClassLabel(num_classes=<span class="hljs-number">9</span>, names=[<span class="hljs-string">&#x27;O&#x27;</span>, <span class="hljs-string">&#x27;B-PER&#x27;</span>, <span class="hljs-string">&#x27;I-PER&#x27;</span>, <span class="hljs-string">&#x27;B-ORG&#x27;</span>, <span class="hljs-string">&#x27;I-ORG&#x27;</span>, <span class="hljs-string">&#x27;B-LOC&#x27;</span>, <span class="hljs-string">&#x27;I-LOC&#x27;</span>, <span class="hljs-string">&#x27;B-MISC&#x27;</span>, <span class="hljs-string">&#x27;I-MISC&#x27;</span>], names_file=<span class="hljs-literal">None</span>, <span class="hljs-built_in">id</span>=<span class="hljs-literal">None</span>), length=-<span class="hljs-number">1</span>, <span class="hljs-built_in">id</span>=<span class="hljs-literal">None</span>)'}}),Yt=new q({props:{code:`label_names = ner_feature.feature.names
label_names`,highlighted:`label_names = ner_feature.feature.names
label_names`}}),We=new q({props:{code:"['O', 'B-PER', 'I-PER', 'B-ORG', 'I-ORG', 'B-LOC', 'I-LOC', 'B-MISC', 'I-MISC']",highlighted:'[<span class="hljs-string">&#x27;O&#x27;</span>, <span class="hljs-string">&#x27;B-PER&#x27;</span>, <span class="hljs-string">&#x27;I-PER&#x27;</span>, <span class="hljs-string">&#x27;B-ORG&#x27;</span>, <span class="hljs-string">&#x27;I-ORG&#x27;</span>, <span class="hljs-string">&#x27;B-LOC&#x27;</span>, <span class="hljs-string">&#x27;I-LOC&#x27;</span>, <span class="hljs-string">&#x27;B-MISC&#x27;</span>, <span class="hljs-string">&#x27;I-MISC&#x27;</span>]'}}),Ma=new q({props:{code:`words = raw_datasets["train"][0]["tokens"]
labels = raw_datasets["train"][0]["ner_tags"]
line1 = ""
line2 = ""
for word, label in zip(words, labels):
    full_label = label_names[label]
    max_length = max(len(word), len(full_label))
    line1 += word + " " * (max_length - len(word) + 1)
    line2 += full_label + " " * (max_length - len(full_label) + 1)

print(line1)
print(line2)`,highlighted:`words = raw_datasets[<span class="hljs-string">&quot;train&quot;</span>][<span class="hljs-number">0</span>][<span class="hljs-string">&quot;tokens&quot;</span>]
labels = raw_datasets[<span class="hljs-string">&quot;train&quot;</span>][<span class="hljs-number">0</span>][<span class="hljs-string">&quot;ner_tags&quot;</span>]
line1 = <span class="hljs-string">&quot;&quot;</span>
line2 = <span class="hljs-string">&quot;&quot;</span>
<span class="hljs-keyword">for</span> word, label <span class="hljs-keyword">in</span> <span class="hljs-built_in">zip</span>(words, labels):
    full_label = label_names[label]
    max_length = <span class="hljs-built_in">max</span>(<span class="hljs-built_in">len</span>(word), <span class="hljs-built_in">len</span>(full_label))
    line1 += word + <span class="hljs-string">&quot; &quot;</span> * (max_length - <span class="hljs-built_in">len</span>(word) + <span class="hljs-number">1</span>)
    line2 += full_label + <span class="hljs-string">&quot; &quot;</span> * (max_length - <span class="hljs-built_in">len</span>(full_label) + <span class="hljs-number">1</span>)

<span class="hljs-built_in">print</span>(line1)
<span class="hljs-built_in">print</span>(line2)`}}),Ls=new q({props:{code:`'EU    rejects German call to boycott British lamb .'
'B-ORG O       B-MISC O    O  O       B-MISC  O    O'`,highlighted:`<span class="hljs-string">&#x27;EU    rejects German call to boycott British lamb .&#x27;</span>
<span class="hljs-string">&#x27;B-ORG O       B-MISC O    O  O       B-MISC  O    O&#x27;</span>`}}),Xt=new q({props:{code:`'Germany \\'s representative to the European Union \\'s veterinary committee Werner Zwingmann said on Wednesday consumers should buy sheepmeat from countries other than Britain until the scientific advice was clearer .'
'B-LOC   O  O              O  O   B-ORG    I-ORG O  O          O         B-PER  I-PER     O    O  O         O         O      O   O         O    O         O     O    B-LOC   O     O   O          O      O   O       O'`,highlighted:`<span class="hljs-string">&#x27;Germany \\&#x27;s representative to the European Union \\&#x27;s veterinary committee Werner Zwingmann said on Wednesday consumers should buy sheepmeat from countries other than Britain until the scientific advice was clearer .&#x27;</span>
<span class="hljs-string">&#x27;B-LOC   O  O              O  O   B-ORG    I-ORG O  O          O         B-PER  I-PER     O    O  O         O         O      O   O         O    O         O     O    B-LOC   O     O   O          O      O   O       O&#x27;</span>`}}),at=new Lo({props:{$$slots:{default:[kd]},$$scope:{ctx:U}}}),Ms=new Ct({}),Hs=new id({props:{id:"iY2AZYdZAr0"}}),Ua=new q({props:{code:`from transformers import AutoTokenizer

model_checkpoint = "bert-base-cased"
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoTokenizer

model_checkpoint = <span class="hljs-string">&quot;bert-base-cased&quot;</span>
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)`}}),Za=new q({props:{code:"tokenizer.is_fast",highlighted:"tokenizer.is_fast"}}),Ks=new q({props:{code:"True",highlighted:'<span class="hljs-literal">True</span>'}}),ka=new q({props:{code:`inputs = tokenizer(raw_datasets["train"][0]["tokens"], is_split_into_words=True)
inputs.tokens()`,highlighted:`inputs = tokenizer(raw_datasets[<span class="hljs-string">&quot;train&quot;</span>][<span class="hljs-number">0</span>][<span class="hljs-string">&quot;tokens&quot;</span>], is_split_into_words=<span class="hljs-literal">True</span>)
inputs.tokens()`}}),ya=new q({props:{code:"['[CLS]', 'EU', 'rejects', 'German', 'call', 'to', 'boycott', 'British', 'la', '##mb', '.', '[SEP]']",highlighted:'[<span class="hljs-string">&#x27;[CLS]&#x27;</span>, <span class="hljs-string">&#x27;EU&#x27;</span>, <span class="hljs-string">&#x27;rejects&#x27;</span>, <span class="hljs-string">&#x27;German&#x27;</span>, <span class="hljs-string">&#x27;call&#x27;</span>, <span class="hljs-string">&#x27;to&#x27;</span>, <span class="hljs-string">&#x27;boycott&#x27;</span>, <span class="hljs-string">&#x27;British&#x27;</span>, <span class="hljs-string">&#x27;la&#x27;</span>, <span class="hljs-string">&#x27;##mb&#x27;</span>, <span class="hljs-string">&#x27;.&#x27;</span>, <span class="hljs-string">&#x27;[SEP]&#x27;</span>]'}}),Ka=new q({props:{code:"inputs.word_ids()",highlighted:"inputs.word_ids()"}}),Va=new q({props:{code:"[None, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, None]",highlighted:'[<span class="hljs-literal">None</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-literal">None</span>]'}}),Pl=new q({props:{code:`def align_labels_with_tokens(labels, word_ids):
    new_labels = []
    current_word = None
    for word_id in word_ids:
        if word_id != current_word:
            # Start of a new word!
            current_word = word_id
            label = -100 if word_id is None else labels[word_id]
            new_labels.append(label)
        elif word_id is None:
            # Special token
            new_labels.append(-100)
        else:
            # Same word as previous token
            label = labels[word_id]
            # If the label is B-XXX we change it to I-XXX
            if label % 2 == 1:
                label += 1
            new_labels.append(label)

    return new_labels`,highlighted:`<span class="hljs-keyword">def</span> <span class="hljs-title function_">align_labels_with_tokens</span>(<span class="hljs-params">labels, word_ids</span>):
    new_labels = []
    current_word = <span class="hljs-literal">None</span>
    <span class="hljs-keyword">for</span> word_id <span class="hljs-keyword">in</span> word_ids:
        <span class="hljs-keyword">if</span> word_id != current_word:
            <span class="hljs-comment"># Start of a new word!</span>
            current_word = word_id
            label = -<span class="hljs-number">100</span> <span class="hljs-keyword">if</span> word_id <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span> <span class="hljs-keyword">else</span> labels[word_id]
            new_labels.append(label)
        <span class="hljs-keyword">elif</span> word_id <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            <span class="hljs-comment"># Special token</span>
            new_labels.append(-<span class="hljs-number">100</span>)
        <span class="hljs-keyword">else</span>:
            <span class="hljs-comment"># Same word as previous token</span>
            label = labels[word_id]
            <span class="hljs-comment"># If the label is B-XXX we change it to I-XXX</span>
            <span class="hljs-keyword">if</span> label % <span class="hljs-number">2</span> == <span class="hljs-number">1</span>:
                label += <span class="hljs-number">1</span>
            new_labels.append(label)

    <span class="hljs-keyword">return</span> new_labels`}}),ql=new q({props:{code:`labels = raw_datasets["train"][0]["ner_tags"]
word_ids = inputs.word_ids()
print(labels)
print(align_labels_with_tokens(labels, word_ids))`,highlighted:`labels = raw_datasets[<span class="hljs-string">&quot;train&quot;</span>][<span class="hljs-number">0</span>][<span class="hljs-string">&quot;ner_tags&quot;</span>]
word_ids = inputs.word_ids()
<span class="hljs-built_in">print</span>(labels)
<span class="hljs-built_in">print</span>(align_labels_with_tokens(labels, word_ids))`}}),Al=new q({props:{code:`[3, 0, 7, 0, 0, 0, 7, 0, 0]
[-100, 3, 0, 7, 0, 0, 0, 7, 0, 0, 0, -100]`,highlighted:`[<span class="hljs-number">3</span>, <span class="hljs-number">0</span>, <span class="hljs-number">7</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">7</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>]
[-<span class="hljs-number">100</span>, <span class="hljs-number">3</span>, <span class="hljs-number">0</span>, <span class="hljs-number">7</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">7</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">100</span>]`}}),Ja=new Lo({props:{$$slots:{default:[$d]},$$scope:{ctx:U}}}),Nl=new q({props:{code:`def tokenize_and_align_labels(examples):
    tokenized_inputs = tokenizer(
        examples["tokens"], truncation=True, is_split_into_words=True
    )
    all_labels = examples["ner_tags"]
    new_labels = []
    for i, labels in enumerate(all_labels):
        word_ids = tokenized_inputs.word_ids(i)
        new_labels.append(align_labels_with_tokens(labels, word_ids))

    tokenized_inputs["labels"] = new_labels
    return tokenized_inputs`,highlighted:`<span class="hljs-keyword">def</span> <span class="hljs-title function_">tokenize_and_align_labels</span>(<span class="hljs-params">examples</span>):
    tokenized_inputs = tokenizer(
        examples[<span class="hljs-string">&quot;tokens&quot;</span>], truncation=<span class="hljs-literal">True</span>, is_split_into_words=<span class="hljs-literal">True</span>
    )
    all_labels = examples[<span class="hljs-string">&quot;ner_tags&quot;</span>]
    new_labels = []
    <span class="hljs-keyword">for</span> i, labels <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(all_labels):
        word_ids = tokenized_inputs.word_ids(i)
        new_labels.append(align_labels_with_tokens(labels, word_ids))

    tokenized_inputs[<span class="hljs-string">&quot;labels&quot;</span>] = new_labels
    <span class="hljs-keyword">return</span> tokenized_inputs`}}),xt=new q({props:{code:`tokenized_datasets = raw_datasets.map(
    tokenize_and_align_labels,
    batched=True,
    remove_columns=raw_datasets["train"].column_names,
)`,highlighted:`tokenized_datasets = raw_datasets.<span class="hljs-built_in">map</span>(
    tokenize_and_align_labels,
    batched=<span class="hljs-literal">True</span>,
    remove_columns=raw_datasets[<span class="hljs-string">&quot;train&quot;</span>].column_names,
)`}});const nc=[jd,yd],Kr=[];function oc(e,u){return e[0]==="pt"?0:1}Ot=oc(U),gs=Kr[Ot]=nc[Ot](U),Fl=new Ct({});const rc=[xd,Ed],Vr=[];function ic(e,u){return e[0]==="pt"?0:1}$s=ic(U),ys=Vr[$s]=rc[$s](U),js=new q({props:{code:`batch = data_collator([tokenized_datasets["train"][i] for i in range(2)])
batch["labels"]`,highlighted:`batch = data_collator([tokenized_datasets[<span class="hljs-string">&quot;train&quot;</span>][i] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">2</span>)])
batch[<span class="hljs-string">&quot;labels&quot;</span>]`}}),Hl=new q({props:{code:`tensor([[-100,    3,    0,    7,    0,    0,    0,    7,    0,    0,    0, -100],
        [-100,    1,    2, -100, -100, -100, -100, -100, -100, -100, -100, -100]])`,highlighted:`tensor([[-<span class="hljs-number">100</span>,    <span class="hljs-number">3</span>,    <span class="hljs-number">0</span>,    <span class="hljs-number">7</span>,    <span class="hljs-number">0</span>,    <span class="hljs-number">0</span>,    <span class="hljs-number">0</span>,    <span class="hljs-number">7</span>,    <span class="hljs-number">0</span>,    <span class="hljs-number">0</span>,    <span class="hljs-number">0</span>, -<span class="hljs-number">100</span>],
        [-<span class="hljs-number">100</span>,    <span class="hljs-number">1</span>,    <span class="hljs-number">2</span>, -<span class="hljs-number">100</span>, -<span class="hljs-number">100</span>, -<span class="hljs-number">100</span>, -<span class="hljs-number">100</span>, -<span class="hljs-number">100</span>, -<span class="hljs-number">100</span>, -<span class="hljs-number">100</span>, -<span class="hljs-number">100</span>, -<span class="hljs-number">100</span>]])`}}),Fr=new q({props:{code:`for i in range(2):
    print(tokenized_datasets["train"][i]["labels"])`,highlighted:`<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">2</span>):
    <span class="hljs-built_in">print</span>(tokenized_datasets[<span class="hljs-string">&quot;train&quot;</span>][i][<span class="hljs-string">&quot;labels&quot;</span>])`}}),Lr=new q({props:{code:`[-100, 3, 0, 7, 0, 0, 0, 7, 0, 0, 0, -100]
[-100, 1, 2, -100]`,highlighted:`[-<span class="hljs-number">100</span>, <span class="hljs-number">3</span>, <span class="hljs-number">0</span>, <span class="hljs-number">7</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">7</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">100</span>]
[-<span class="hljs-number">100</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, -<span class="hljs-number">100</span>]`}});const pc=[Cd,Od],Jr=[];function cc(e,u){return e[0]==="pt"?0:1}al=cc(U),ll=Jr[al]=pc[al](U);let Ge=U[0]==="tf"&&pd(U);Rr=new Ct({});const hc=[zd,Pd],Qr=[];function dc(e,u){return e[0]==="pt"?0:1}nl=dc(U),ol=Qr[nl]=hc[nl](U),Br=new q({props:{code:`import evaluate

metric = evaluate.load("seqeval")`,highlighted:`<span class="hljs-keyword">import</span> evaluate

metric = evaluate.load(<span class="hljs-string">&quot;seqeval&quot;</span>)`}}),Mr=new q({props:{code:`labels = raw_datasets["train"][0]["ner_tags"]
labels = [label_names[i] for i in labels]
labels`,highlighted:`labels = raw_datasets[<span class="hljs-string">&quot;train&quot;</span>][<span class="hljs-number">0</span>][<span class="hljs-string">&quot;ner_tags&quot;</span>]
labels = [label_names[i] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> labels]
labels`}}),Hr=new q({props:{code:"['B-ORG', 'O', 'B-MISC', 'O', 'O', 'O', 'B-MISC', 'O', 'O']",highlighted:'[<span class="hljs-string">&#x27;B-ORG&#x27;</span>, <span class="hljs-string">&#x27;O&#x27;</span>, <span class="hljs-string">&#x27;B-MISC&#x27;</span>, <span class="hljs-string">&#x27;O&#x27;</span>, <span class="hljs-string">&#x27;O&#x27;</span>, <span class="hljs-string">&#x27;O&#x27;</span>, <span class="hljs-string">&#x27;B-MISC&#x27;</span>, <span class="hljs-string">&#x27;O&#x27;</span>, <span class="hljs-string">&#x27;O&#x27;</span>]'}}),Wr=new q({props:{code:`predictions = labels.copy()
predictions[2] = "O"
metric.compute(predictions=[predictions], references=[labels])`,highlighted:`predictions = labels.copy()
predictions[<span class="hljs-number">2</span>] = <span class="hljs-string">&quot;O&quot;</span>
metric.compute(predictions=[predictions], references=[labels])`}}),Gr=new q({props:{code:`{'MISC': {'precision': 1.0, 'recall': 0.5, 'f1': 0.67, 'number': 2},
 'ORG': {'precision': 1.0, 'recall': 1.0, 'f1': 1.0, 'number': 1},
 'overall_precision': 1.0,
 'overall_recall': 0.67,
 'overall_f1': 0.8,
 'overall_accuracy': 0.89}`,highlighted:`{<span class="hljs-string">&#x27;MISC&#x27;</span>: {<span class="hljs-string">&#x27;precision&#x27;</span>: <span class="hljs-number">1.0</span>, <span class="hljs-string">&#x27;recall&#x27;</span>: <span class="hljs-number">0.5</span>, <span class="hljs-string">&#x27;f1&#x27;</span>: <span class="hljs-number">0.67</span>, <span class="hljs-string">&#x27;number&#x27;</span>: <span class="hljs-number">2</span>},
 <span class="hljs-string">&#x27;ORG&#x27;</span>: {<span class="hljs-string">&#x27;precision&#x27;</span>: <span class="hljs-number">1.0</span>, <span class="hljs-string">&#x27;recall&#x27;</span>: <span class="hljs-number">1.0</span>, <span class="hljs-string">&#x27;f1&#x27;</span>: <span class="hljs-number">1.0</span>, <span class="hljs-string">&#x27;number&#x27;</span>: <span class="hljs-number">1</span>},
 <span class="hljs-string">&#x27;overall_precision&#x27;</span>: <span class="hljs-number">1.0</span>,
 <span class="hljs-string">&#x27;overall_recall&#x27;</span>: <span class="hljs-number">0.67</span>,
 <span class="hljs-string">&#x27;overall_f1&#x27;</span>: <span class="hljs-number">0.8</span>,
 <span class="hljs-string">&#x27;overall_accuracy&#x27;</span>: <span class="hljs-number">0.89</span>}`}});const uc=[Ad,qd],ei=[];function fc(e,u){return e[0]==="pt"?0:1}rl=fc(U),il=ei[rl]=uc[rl](U);let Ue=U[0]==="pt"&&cd(U);return Ur=new Ct({}),Yr=new q({props:{code:`from transformers import pipeline

# Replace this with your own checkpoint
model_checkpoint = "huggingface-course/bert-finetuned-ner"
token_classifier = pipeline(
    "token-classification", model=model_checkpoint, aggregation_strategy="simple"
)
token_classifier("My name is Sylvain and I work at Hugging Face in Brooklyn.")`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> pipeline

<span class="hljs-comment"># Replace this with your own checkpoint</span>
model_checkpoint = <span class="hljs-string">&quot;huggingface-course/bert-finetuned-ner&quot;</span>
token_classifier = pipeline(
    <span class="hljs-string">&quot;token-classification&quot;</span>, model=model_checkpoint, aggregation_strategy=<span class="hljs-string">&quot;simple&quot;</span>
)
token_classifier(<span class="hljs-string">&quot;My name is Sylvain and I work at Hugging Face in Brooklyn.&quot;</span>)`}}),Xr=new q({props:{code:`[{'entity_group': 'PER', 'score': 0.9988506, 'word': 'Sylvain', 'start': 11, 'end': 18},
 {'entity_group': 'ORG', 'score': 0.9647625, 'word': 'Hugging Face', 'start': 33, 'end': 45},
 {'entity_group': 'LOC', 'score': 0.9986118, 'word': 'Brooklyn', 'start': 49, 'end': 57}]`,highlighted:`[{<span class="hljs-string">&#x27;entity_group&#x27;</span>: <span class="hljs-string">&#x27;PER&#x27;</span>, <span class="hljs-string">&#x27;score&#x27;</span>: <span class="hljs-number">0.9988506</span>, <span class="hljs-string">&#x27;word&#x27;</span>: <span class="hljs-string">&#x27;Sylvain&#x27;</span>, <span class="hljs-string">&#x27;start&#x27;</span>: <span class="hljs-number">11</span>, <span class="hljs-string">&#x27;end&#x27;</span>: <span class="hljs-number">18</span>},
 {<span class="hljs-string">&#x27;entity_group&#x27;</span>: <span class="hljs-string">&#x27;ORG&#x27;</span>, <span class="hljs-string">&#x27;score&#x27;</span>: <span class="hljs-number">0.9647625</span>, <span class="hljs-string">&#x27;word&#x27;</span>: <span class="hljs-string">&#x27;Hugging Face&#x27;</span>, <span class="hljs-string">&#x27;start&#x27;</span>: <span class="hljs-number">33</span>, <span class="hljs-string">&#x27;end&#x27;</span>: <span class="hljs-number">45</span>},
 {<span class="hljs-string">&#x27;entity_group&#x27;</span>: <span class="hljs-string">&#x27;LOC&#x27;</span>, <span class="hljs-string">&#x27;score&#x27;</span>: <span class="hljs-number">0.9986118</span>, <span class="hljs-string">&#x27;word&#x27;</span>: <span class="hljs-string">&#x27;Brooklyn&#x27;</span>, <span class="hljs-string">&#x27;start&#x27;</span>: <span class="hljs-number">49</span>, <span class="hljs-string">&#x27;end&#x27;</span>: <span class="hljs-number">57</span>}]`}}),{c(){d=o("meta"),g=c(),j(m.$$.fragment),$=c(),T=o("h1"),v=o("a"),y=o("span"),j(D.$$.fragment),z=c(),N=o("span"),B=a("Token classification"),A=c(),M.c(),G=c(),Z=o("p"),X=a("The first application we\u2019ll explore is token classification. This generic task encompasses any problem that can be formulated as \u201Cattributing a label to each token in a sentence,\u201D such as:"),C=c(),S=o("ul"),P=o("li"),H=o("strong"),F=a("Named entity recognition (NER)"),Y=a(": Find the entities (such as persons, locations, or organizations) in a sentence. This can be formulated as attributing a label to each token by having one class per entity and one class for \u201Cno entity.\u201D"),Q=c(),ee=o("li"),oe=o("strong"),K=a("Part-of-speech tagging (POS)"),de=a(": Mark each word in a sentence as corresponding to a particular part of speech (such as noun, verb, adjective, etc.)."),J=c(),W=o("li"),R=o("strong"),le=a("Chunking"),ue=a(": Find the tokens that belong to the same entity. This task (which can be combined with POS or NER) can be formulated as attributing one label (usually "),ye=o("code"),ne=a("B-"),Fe=a(") to any tokens that are at the beginning of a chunk, another label (usually "),V=o("code"),nt=a("I-"),pe=a(") to tokens that are inside a chunk, and a third label (usually "),dt=o("code"),Qt=a("O"),ot=a(") to tokens that don\u2019t belong to any chunk."),ea=c(),j(Tt.$$.fragment),es=c(),we=o("p"),Es=a("Of course, there are many other types of token classification problem; those are just a few representative examples. In this section, we will fine-tune a model (BERT) on a NER task, which will then be able to compute predictions like this one:"),Te=c(),fe=o("iframe"),ts=c(),se=o("a"),ce=o("img"),Le=c(),Dt=o("img"),ta=c(),Xe=o("p"),Re=a("You can find the model we\u2019ll train and upload to the Hub and double-check its predictions "),Pt=o("a"),ls=a("here"),zt=a("."),xs=c(),je=o("h2"),De=o("a"),qt=o("span"),j(Ee.$$.fragment),Da=c(),At=o("span"),Ze=a("Preparing the data"),Os=c(),ie=o("p"),It=a("First things first, we need a dataset suitable for token classification. In this section we will use the "),Ke=o("a"),ut=a("CoNLL-2003 dataset"),Pa=a(", which contains news stories from Reuters."),ft=c(),j(mt.$$.fragment),sa=c(),Pe=o("h3"),ze=o("a"),ns=o("span"),j(te.$$.fragment),Nt=c(),_t=o("span"),Ve=a("The CoNLL-2003 dataset"),aa=c(),qe=o("p"),za=a("To load the CoNLL-2003 dataset, we use the "),Cs=o("code"),Je=a("load_dataset()"),Ts=a(" method from the \u{1F917} Datasets library:"),la=c(),j(bt.$$.fragment),rt=c(),Qe=o("p"),Ds=a("This will download and cache the dataset, like we saw in "),os=o("a"),Ps=a("Chapter 3"),na=a(" for the GLUE MRPC dataset. Inspecting this object shows us the columns present and the split between the training, validation, and test sets:"),wt=c(),j(et.$$.fragment),me=c(),j(St.$$.fragment),Ft=c(),Ae=o("p"),oa=a("In particular, we can see the dataset contains labels for the three tasks we mentioned earlier: NER, POS, and chunking. A big difference from other datasets is that the input texts are not presented as sentences or documents, but lists of words (the last column is called "),_e=o("code"),zs=a("tokens"),qs=a(", but it contains words in the sense that these are pre-tokenized inputs that still need to go through the tokenizer for subword tokenization)."),ra=c(),rs=o("p"),is=a("Let\u2019s have a look at the first element of the training set:"),gt=c(),j(vt.$$.fragment),it=c(),j(Lt.$$.fragment),As=c(),Ie=o("p"),Rt=a("Since we want to perform named entity recognition, we will look at the NER tags:"),Bt=c(),j(tt.$$.fragment),ia=c(),j(pt.$$.fragment),Be=c(),ct=o("p"),Mt=a("Those are the labels as integers ready for training, but they\u2019re not necessarily useful when we want to inspect the data. Like for text classification, we can access the correspondence between those integers and the label names by looking at the "),f=o("code"),L=a("features"),ps=a(" attribute of our dataset:"),pa=c(),j(Me.$$.fragment),Ht=c(),j(kt.$$.fragment),qa=c(),re=o("p"),Aa=a("So this column contains elements that are sequences of "),Wt=o("code"),ca=a("ClassLabel"),Ia=a("s. The type of the elements of the sequence is in the "),ge=o("code"),Gt=a("feature"),ha=a(" attribute of this "),st=o("code"),pl=a("ner_feature"),da=a(", and we can access the list of names by looking at the "),ua=o("code"),Na=a("names"),Ut=a(" attribute of that "),fa=o("code"),He=a("feature"),cl=a(":"),Sa=c(),j(Yt.$$.fragment),xe=c(),j(We.$$.fragment),Is=c(),be=o("p"),hl=a("We already saw these labels when digging into the "),ve=o("code"),dl=a("token-classification"),ma=a(" pipeline in "),ke=o("a"),ul=a("Chapter 6"),_a=a(", but for a quick refresher:"),Fa=c(),Oe=o("ul"),ba=o("li"),Xl=o("code"),Ro=a("O"),Zl=a(" means the word doesn\u2019t correspond to any entity."),Bo=c(),cs=o("li"),fl=o("code"),La=a("B-PER"),Ln=a("/"),wa=o("code"),Mo=a("I-PER"),Rn=a(" means the word corresponds to the beginning of/is inside a "),Ns=o("em"),Bn=a("person"),hs=a(" entity."),Ho=c(),$t=o("li"),Kl=o("code"),Wo=a("B-ORG"),Vl=a("/"),Jl=o("code"),Go=a("I-ORG"),Mn=a(" means the word corresponds to the beginning of/is inside an "),Ss=o("em"),Hn=a("organization"),ga=a(" entity."),Uo=c(),yt=o("li"),Ql=o("code"),Yo=a("B-LOC"),Wn=a("/"),Fs=o("code"),Gn=a("I-LOC"),Ra=a(" means the word corresponds to the beginning of/is inside a "),ml=o("em"),ds=a("location"),Xo=a(" entity."),en=c(),us=o("li"),tn=o("code"),sn=a("B-MISC"),Zo=a("/"),an=o("code"),Un=a("I-MISC"),Ba=a(" means the word corresponds to the beginning of/is inside a "),_l=o("em"),jt=a("miscellaneous"),Ko=a(" entity."),bl=c(),wl=o("p"),Vo=a("Now decoding the labels we saw earlier gives us this:"),gl=c(),j(Ma.$$.fragment),Yn=c(),j(Ls.$$.fragment),Xn=c(),fs=o("p"),Zn=a("And for an example mixing "),Rs=o("code"),Kn=a("B-"),Ha=a(" and "),vl=o("code"),kl=a("I-"),Jo=a(" labels, here\u2019s what the same code gives us on the element of the training set at index 4:"),ln=c(),j(Xt.$$.fragment),nn=c(),Ce=o("p"),Qo=a("As we can see, entities spanning two words, like \u201CEuropean Union\u201D and \u201CWerner Zwingmann,\u201D are attributed a "),Wa=o("code"),er=a("B-"),tr=a(" label for the first word and an "),Ga=o("code"),sr=a("I-"),ar=a(" label for the second."),on=c(),j(at.$$.fragment),Bs=c(),Zt=o("h3"),Et=o("a"),rn=o("span"),j(Ms.$$.fragment),lr=c(),$l=o("span"),ms=a("Processing the data"),Vn=c(),j(Hs.$$.fragment),Jn=c(),_s=o("p"),pn=a("As usual, our texts need to be converted to token IDs before the model can make sense of them. As we saw in "),yl=o("a"),nr=a("Chapter 6"),Qn=a(", a big difference in the case of token classification tasks is that we have pre-tokenized inputs. Fortunately, the tokenizer API can deal with that pretty easily; we just need to warn the "),Ws=o("code"),eo=a("tokenizer"),jl=a(" with a special flag."),to=c(),Gs=o("p"),bs=a("To begin, let\u2019s create our "),Us=o("code"),or=a("tokenizer"),cn=a(" object. As we said before, we will be using a BERT pretrained model, so we\u2019ll start by downloading and caching the associated tokenizer:"),so=c(),j(Ua.$$.fragment),ao=c(),ae=o("p"),rr=a("You can replace the "),Ya=o("code"),ir=a("model_checkpoint"),pr=a(" with any other model you prefer from the "),Ys=o("a"),cr=a("Hub"),hr=a(", or with a local folder in which you\u2019ve saved a pretrained model and a tokenizer. The only constraint is that the tokenizer needs to be backed by the \u{1F917} Tokenizers library, so there\u2019s a \u201Cfast\u201D version available. You can see all the architectures that come with a fast version in "),Xs=o("a"),dr=a("this big table"),ur=a(", and to check that the "),Xa=o("code"),fr=a("tokenizer"),mr=a(" object you\u2019re using is indeed backed by \u{1F917} Tokenizers you can look at its "),hn=o("code"),Zs=a("is_fast"),_r=a(" attribute:"),El=c(),j(Za.$$.fragment),lo=c(),j(Ks.$$.fragment),no=c(),ws=o("p"),oo=a("To tokenize a pre-tokenized input, we can use our "),va=o("code"),br=a("tokenizer"),ro=a(" as usual and just add "),Vs=o("code"),io=a("is_split_into_words=True"),xl=a(":"),po=c(),j(ka.$$.fragment),$a=c(),j(ya.$$.fragment),he=c(),Ne=o("p"),dn=a("As we can see, the tokenizer added the special tokens used by the model ("),un=o("code"),wr=a("[CLS]"),fn=a(" at the beginning and "),mn=o("code"),gr=a("[SEP]"),_n=a(" at the end) and left most of the words untouched. The word "),bn=o("code"),vr=a("lamb"),wn=a(", however, was tokenized into two subwords, "),gn=o("code"),kr=a("la"),vn=a(" and "),kn=o("code"),$r=a("##mb"),$n=a(". This introduces a mismatch between our inputs and the labels: the list of labels has only 9 elements, whereas our input now has 12 tokens. Accounting for the special tokens is easy (we know they are at the beginning and the end), but we also need to make sure we align all the labels with the proper words."),co=c(),ja=o("p"),yn=a("Fortunately, because we\u2019re using a fast tokenizer we have access to the \u{1F917} Tokenizers superpowers, which means we can easily map each token to its corresponding word (as seen in "),Ol=o("a"),yr=a("Chapter 6"),ho=a("):"),Kt=c(),j(Ka.$$.fragment),Cl=c(),j(Va.$$.fragment),uo=c(),$e=o("p"),jn=a("With a tiny bit of work, we can then expand our label list to match the tokens. The first rule we\u2019ll apply is that special tokens get a label of "),En=o("code"),jr=a("-100"),fo=a(". This is because by default "),n=o("code"),_=a("-100"),ii=a(" is an index that is ignored in the loss function we will use (cross entropy). Then, each token gets the same label as the token that started the word it\u2019s inside, since they are part of the same entity. For tokens inside a word but not at the beginning, we replace the "),mo=o("code"),pi=a("B-"),Tl=a(" with "),_o=o("code"),ci=a("I-"),Dl=a(" (since the token does not begin the entity):"),Er=c(),j(Pl.$$.fragment),xn=c(),On=o("p"),zl=a("Let\u2019s try it out on our first sentence:"),xr=c(),j(ql.$$.fragment),Cn=c(),j(Al.$$.fragment),Or=c(),Js=o("p"),bo=a("As we can see, our function added the "),wo=o("code"),hi=a("-100"),di=a(" for the two special tokens at the beginning and the end, and a new "),Il=o("code"),ui=a("0"),lt=a(" for our word that was split into two tokens."),Cr=c(),j(Ja.$$.fragment),go=c(),ht=o("p"),fi=a("To preprocess our whole dataset, we need to tokenize all the inputs and apply "),vo=o("code"),mi=a("align_labels_with_tokens()"),ko=a(" on all the labels. To take advantage of the speed of our fast tokenizer, it\u2019s best to tokenize lots of texts at the same time, so we\u2019ll write a function that processes a list of examples and use the "),$o=o("code"),_i=a("Dataset.map()"),yo=a(" method with the option "),jo=o("code"),bi=a("batched=True"),Eo=a(". The only thing that is different from our previous example is that the "),xo=o("code"),wi=a("word_ids()"),Oo=a(" function needs to get the index of the example we want the word IDs of when the inputs to the tokenizer are lists of texts (or in our case, list of lists of words), so we add that too:"),Tr=c(),j(Nl.$$.fragment),Dr=c(),Qa=o("p"),gi=a("Note that we haven\u2019t padded our inputs yet; we\u2019ll do that later, when creating the batches with a data collator."),Tn=c(),Dn=o("p"),vi=a("We can now apply all that preprocessing in one go on the other splits of our dataset:"),Pr=c(),j(xt.$$.fragment),zr=c(),el=o("p"),ki=a("We\u2019ve done the hardest part! Now that the data has been preprocessed, the actual training will look a lot like what we did in "),Pn=o("a"),Sl=a("Chapter 3"),$i=a("."),qr=c(),gs.c(),Qs=c(),Ea=o("h3"),tl=o("a"),vs=o("span"),j(Fl.$$.fragment),yi=c(),Co=o("span"),ji=a("Data collation"),sl=c(),Vt=o("p"),Ei=a("We can\u2019t just use a "),Ll=o("code"),xi=a("DataCollatorWithPadding"),Oi=a(" like in "),zn=o("a"),Rl=a("Chapter 3"),Ci=a(" because that only pads the inputs (input IDs, attention mask, and token type IDs). Here our labels should be padded the exact same way as the inputs so that they stay the same size, using "),To=o("code"),Ti=a("-100"),Bl=a(" as a value so that the corresponding predictions are ignored in the loss computation."),qn=c(),Jt=o("p"),ks=a("This is all done by a "),Ml=o("a"),Do=o("code"),Di=a("DataCollatorForTokenClassification"),Pi=a(". Like the "),xa=o("code"),zi=a("DataCollatorWithPadding"),qi=a(", it takes the "),Po=o("code"),Ai=a("tokenizer"),Se=a(" used to preprocess the inputs:"),Ar=c(),ys.c(),An=c(),In=o("p"),Ii=a("To test this on a few samples, we can just call it on a list of examples from our tokenized training set:"),Ir=c(),j(js.$$.fragment),Nr=c(),j(Hl.$$.fragment),Sr=c(),Ni=o("p"),Hp=a("Let\u2019s compare this to the labels for the first and second elements in our dataset:"),pp=c(),j(Fr.$$.fragment),cp=c(),j(Lr.$$.fragment),hp=c(),ll.c(),Si=c(),Ge&&Ge.c(),Fi=c(),Nn=o("h3"),zo=o("a"),tp=o("span"),j(Rr.$$.fragment),Wp=c(),sp=o("span"),Gp=a("Metrics"),dp=c(),ol.c(),Li=c(),j(Br.$$.fragment),up=c(),Ri=o("p"),Up=a("This metric does not behave like the standard accuracy: it will actually take the lists of labels as strings, not integers, so we will need to fully decode the predictions and labels before passing them to the metric. Let\u2019s see how it works. First, we\u2019ll get the labels for our first training example:"),fp=c(),j(Mr.$$.fragment),mp=c(),j(Hr.$$.fragment),_p=c(),Bi=o("p"),Yp=a("We can then create fake predictions for those by just changing the value at index 2:"),bp=c(),j(Wr.$$.fragment),wp=c(),Mi=o("p"),Xp=a("Note that the metric takes a list of predictions (not just one) and a list of labels. Here\u2019s the output:"),gp=c(),j(Gr.$$.fragment),vp=c(),il.c(),Hi=c(),Ue&&Ue.c(),Wi=c(),Sn=o("h2"),qo=o("a"),ap=o("span"),j(Ur.$$.fragment),Zp=c(),lp=o("span"),Kp=a("Using the fine-tuned model"),kp=c(),Ao=o("p"),Vp=a("We\u2019ve already shown you how you can use the model we fine-tuned on the Model Hub with the inference widget. To use it locally in a "),np=o("code"),Jp=a("pipeline"),Qp=a(", you just have to specify the proper model identifier:"),$p=c(),j(Yr.$$.fragment),yp=c(),j(Xr.$$.fragment),jp=c(),Gi=o("p"),ec=a("Great! Our model is working as well as the default one for this pipeline!"),this.h()},l(e){const u=md('[data-svelte="svelte-1phssyn"]',document.head);d=r(u,"META",{name:!0,content:!0}),u.forEach(s),g=h(e),E(m.$$.fragment,e),$=h(e),T=r(e,"H1",{class:!0});var ti=i(T);v=r(ti,"A",{id:!0,class:!0,href:!0});var Ui=i(v);y=r(Ui,"SPAN",{});var op=i(y);E(D.$$.fragment,op),op.forEach(s),Ui.forEach(s),z=h(ti),N=r(ti,"SPAN",{});var rp=i(N);B=l(rp,"Token classification"),rp.forEach(s),ti.forEach(s),A=h(e),M.l(e),G=h(e),Z=r(e,"P",{});var ip=i(Z);X=l(ip,"The first application we\u2019ll explore is token classification. This generic task encompasses any problem that can be formulated as \u201Cattributing a label to each token in a sentence,\u201D such as:"),ip.forEach(s),C=h(e),S=r(e,"UL",{});var Wl=i(S);P=r(Wl,"LI",{});var si=i(P);H=r(si,"STRONG",{});var Yi=i(H);F=l(Yi,"Named entity recognition (NER)"),Yi.forEach(s),Y=l(si,": Find the entities (such as persons, locations, or organizations) in a sentence. This can be formulated as attributing a label to each token by having one class per entity and one class for \u201Cno entity.\u201D"),si.forEach(s),Q=h(Wl),ee=r(Wl,"LI",{});var ai=i(ee);oe=r(ai,"STRONG",{});var Xi=i(oe);K=l(Xi,"Part-of-speech tagging (POS)"),Xi.forEach(s),de=l(ai,": Mark each word in a sentence as corresponding to a particular part of speech (such as noun, verb, adjective, etc.)."),ai.forEach(s),J=h(Wl),W=r(Wl,"LI",{});var Fn=i(W);R=r(Fn,"STRONG",{});var mc=i(R);le=l(mc,"Chunking"),mc.forEach(s),ue=l(Fn,": Find the tokens that belong to the same entity. This task (which can be combined with POS or NER) can be formulated as attributing one label (usually "),ye=r(Fn,"CODE",{});var _c=i(ye);ne=l(_c,"B-"),_c.forEach(s),Fe=l(Fn,") to any tokens that are at the beginning of a chunk, another label (usually "),V=r(Fn,"CODE",{});var bc=i(V);nt=l(bc,"I-"),bc.forEach(s),pe=l(Fn,") to tokens that are inside a chunk, and a third label (usually "),dt=r(Fn,"CODE",{});var wc=i(dt);Qt=l(wc,"O"),wc.forEach(s),ot=l(Fn,") to tokens that don\u2019t belong to any chunk."),Fn.forEach(s),Wl.forEach(s),ea=h(e),E(Tt.$$.fragment,e),es=h(e),we=r(e,"P",{});var gc=i(we);Es=l(gc,"Of course, there are many other types of token classification problem; those are just a few representative examples. In this section, we will fine-tune a model (BERT) on a NER task, which will then be able to compute predictions like this one:"),gc.forEach(s),Te=h(e),fe=r(e,"IFRAME",{src:!0,frameborder:!0,height:!0,title:!0,class:!0,allow:!0,sandbox:!0}),i(fe).forEach(s),ts=h(e),se=r(e,"A",{class:!0,href:!0});var xp=i(se);ce=r(xp,"IMG",{class:!0,src:!0,alt:!0}),Le=h(xp),Dt=r(xp,"IMG",{class:!0,src:!0,alt:!0}),xp.forEach(s),ta=h(e),Xe=r(e,"P",{});var Op=i(Xe);Re=l(Op,"You can find the model we\u2019ll train and upload to the Hub and double-check its predictions "),Pt=r(Op,"A",{href:!0,rel:!0});var vc=i(Pt);ls=l(vc,"here"),vc.forEach(s),zt=l(Op,"."),Op.forEach(s),xs=h(e),je=r(e,"H2",{class:!0});var Cp=i(je);De=r(Cp,"A",{id:!0,class:!0,href:!0});var kc=i(De);qt=r(kc,"SPAN",{});var $c=i(qt);E(Ee.$$.fragment,$c),$c.forEach(s),kc.forEach(s),Da=h(Cp),At=r(Cp,"SPAN",{});var yc=i(At);Ze=l(yc,"Preparing the data"),yc.forEach(s),Cp.forEach(s),Os=h(e),ie=r(e,"P",{});var Tp=i(ie);It=l(Tp,"First things first, we need a dataset suitable for token classification. In this section we will use the "),Ke=r(Tp,"A",{href:!0,rel:!0});var jc=i(Ke);ut=l(jc,"CoNLL-2003 dataset"),jc.forEach(s),Pa=l(Tp,", which contains news stories from Reuters."),Tp.forEach(s),ft=h(e),E(mt.$$.fragment,e),sa=h(e),Pe=r(e,"H3",{class:!0});var Dp=i(Pe);ze=r(Dp,"A",{id:!0,class:!0,href:!0});var Ec=i(ze);ns=r(Ec,"SPAN",{});var xc=i(ns);E(te.$$.fragment,xc),xc.forEach(s),Ec.forEach(s),Nt=h(Dp),_t=r(Dp,"SPAN",{});var Oc=i(_t);Ve=l(Oc,"The CoNLL-2003 dataset"),Oc.forEach(s),Dp.forEach(s),aa=h(e),qe=r(e,"P",{});var Pp=i(qe);za=l(Pp,"To load the CoNLL-2003 dataset, we use the "),Cs=r(Pp,"CODE",{});var Cc=i(Cs);Je=l(Cc,"load_dataset()"),Cc.forEach(s),Ts=l(Pp," method from the \u{1F917} Datasets library:"),Pp.forEach(s),la=h(e),E(bt.$$.fragment,e),rt=h(e),Qe=r(e,"P",{});var zp=i(Qe);Ds=l(zp,"This will download and cache the dataset, like we saw in "),os=r(zp,"A",{href:!0});var Tc=i(os);Ps=l(Tc,"Chapter 3"),Tc.forEach(s),na=l(zp," for the GLUE MRPC dataset. Inspecting this object shows us the columns present and the split between the training, validation, and test sets:"),zp.forEach(s),wt=h(e),E(et.$$.fragment,e),me=h(e),E(St.$$.fragment,e),Ft=h(e),Ae=r(e,"P",{});var qp=i(Ae);oa=l(qp,"In particular, we can see the dataset contains labels for the three tasks we mentioned earlier: NER, POS, and chunking. A big difference from other datasets is that the input texts are not presented as sentences or documents, but lists of words (the last column is called "),_e=r(qp,"CODE",{});var Dc=i(_e);zs=l(Dc,"tokens"),Dc.forEach(s),qs=l(qp,", but it contains words in the sense that these are pre-tokenized inputs that still need to go through the tokenizer for subword tokenization)."),qp.forEach(s),ra=h(e),rs=r(e,"P",{});var Pc=i(rs);is=l(Pc,"Let\u2019s have a look at the first element of the training set:"),Pc.forEach(s),gt=h(e),E(vt.$$.fragment,e),it=h(e),E(Lt.$$.fragment,e),As=h(e),Ie=r(e,"P",{});var zc=i(Ie);Rt=l(zc,"Since we want to perform named entity recognition, we will look at the NER tags:"),zc.forEach(s),Bt=h(e),E(tt.$$.fragment,e),ia=h(e),E(pt.$$.fragment,e),Be=h(e),ct=r(e,"P",{});var Ap=i(ct);Mt=l(Ap,"Those are the labels as integers ready for training, but they\u2019re not necessarily useful when we want to inspect the data. Like for text classification, we can access the correspondence between those integers and the label names by looking at the "),f=r(Ap,"CODE",{});var qc=i(f);L=l(qc,"features"),qc.forEach(s),ps=l(Ap," attribute of our dataset:"),Ap.forEach(s),pa=h(e),E(Me.$$.fragment,e),Ht=h(e),E(kt.$$.fragment,e),qa=h(e),re=r(e,"P",{});var Oa=i(re);Aa=l(Oa,"So this column contains elements that are sequences of "),Wt=r(Oa,"CODE",{});var Ac=i(Wt);ca=l(Ac,"ClassLabel"),Ac.forEach(s),Ia=l(Oa,"s. The type of the elements of the sequence is in the "),ge=r(Oa,"CODE",{});var Ic=i(ge);Gt=l(Ic,"feature"),Ic.forEach(s),ha=l(Oa," attribute of this "),st=r(Oa,"CODE",{});var Nc=i(st);pl=l(Nc,"ner_feature"),Nc.forEach(s),da=l(Oa,", and we can access the list of names by looking at the "),ua=r(Oa,"CODE",{});var Sc=i(ua);Na=l(Sc,"names"),Sc.forEach(s),Ut=l(Oa," attribute of that "),fa=r(Oa,"CODE",{});var Fc=i(fa);He=l(Fc,"feature"),Fc.forEach(s),cl=l(Oa,":"),Oa.forEach(s),Sa=h(e),E(Yt.$$.fragment,e),xe=h(e),E(We.$$.fragment,e),Is=h(e),be=r(e,"P",{});var Zi=i(be);hl=l(Zi,"We already saw these labels when digging into the "),ve=r(Zi,"CODE",{});var Lc=i(ve);dl=l(Lc,"token-classification"),Lc.forEach(s),ma=l(Zi," pipeline in "),ke=r(Zi,"A",{href:!0});var Rc=i(ke);ul=l(Rc,"Chapter 6"),Rc.forEach(s),_a=l(Zi,", but for a quick refresher:"),Zi.forEach(s),Fa=h(e),Oe=r(e,"UL",{});var Gl=i(Oe);ba=r(Gl,"LI",{});var tc=i(ba);Xl=r(tc,"CODE",{});var Bc=i(Xl);Ro=l(Bc,"O"),Bc.forEach(s),Zl=l(tc," means the word doesn\u2019t correspond to any entity."),tc.forEach(s),Bo=h(Gl),cs=r(Gl,"LI",{});var li=i(cs);fl=r(li,"CODE",{});var Mc=i(fl);La=l(Mc,"B-PER"),Mc.forEach(s),Ln=l(li,"/"),wa=r(li,"CODE",{});var Hc=i(wa);Mo=l(Hc,"I-PER"),Hc.forEach(s),Rn=l(li," means the word corresponds to the beginning of/is inside a "),Ns=r(li,"EM",{});var Wc=i(Ns);Bn=l(Wc,"person"),Wc.forEach(s),hs=l(li," entity."),li.forEach(s),Ho=h(Gl),$t=r(Gl,"LI",{});var ni=i($t);Kl=r(ni,"CODE",{});var Gc=i(Kl);Wo=l(Gc,"B-ORG"),Gc.forEach(s),Vl=l(ni,"/"),Jl=r(ni,"CODE",{});var Uc=i(Jl);Go=l(Uc,"I-ORG"),Uc.forEach(s),Mn=l(ni," means the word corresponds to the beginning of/is inside an "),Ss=r(ni,"EM",{});var Yc=i(Ss);Hn=l(Yc,"organization"),Yc.forEach(s),ga=l(ni," entity."),ni.forEach(s),Uo=h(Gl),yt=r(Gl,"LI",{});var oi=i(yt);Ql=r(oi,"CODE",{});var Xc=i(Ql);Yo=l(Xc,"B-LOC"),Xc.forEach(s),Wn=l(oi,"/"),Fs=r(oi,"CODE",{});var Zc=i(Fs);Gn=l(Zc,"I-LOC"),Zc.forEach(s),Ra=l(oi," means the word corresponds to the beginning of/is inside a "),ml=r(oi,"EM",{});var Kc=i(ml);ds=l(Kc,"location"),Kc.forEach(s),Xo=l(oi," entity."),oi.forEach(s),en=h(Gl),us=r(Gl,"LI",{});var ri=i(us);tn=r(ri,"CODE",{});var Vc=i(tn);sn=l(Vc,"B-MISC"),Vc.forEach(s),Zo=l(ri,"/"),an=r(ri,"CODE",{});var Jc=i(an);Un=l(Jc,"I-MISC"),Jc.forEach(s),Ba=l(ri," means the word corresponds to the beginning of/is inside a "),_l=r(ri,"EM",{});var Qc=i(_l);jt=l(Qc,"miscellaneous"),Qc.forEach(s),Ko=l(ri," entity."),ri.forEach(s),Gl.forEach(s),bl=h(e),wl=r(e,"P",{});var eh=i(wl);Vo=l(eh,"Now decoding the labels we saw earlier gives us this:"),eh.forEach(s),gl=h(e),E(Ma.$$.fragment,e),Yn=h(e),E(Ls.$$.fragment,e),Xn=h(e),fs=r(e,"P",{});var Ki=i(fs);Zn=l(Ki,"And for an example mixing "),Rs=r(Ki,"CODE",{});var th=i(Rs);Kn=l(th,"B-"),th.forEach(s),Ha=l(Ki," and "),vl=r(Ki,"CODE",{});var sh=i(vl);kl=l(sh,"I-"),sh.forEach(s),Jo=l(Ki," labels, here\u2019s what the same code gives us on the element of the training set at index 4:"),Ki.forEach(s),ln=h(e),E(Xt.$$.fragment,e),nn=h(e),Ce=r(e,"P",{});var Vi=i(Ce);Qo=l(Vi,"As we can see, entities spanning two words, like \u201CEuropean Union\u201D and \u201CWerner Zwingmann,\u201D are attributed a "),Wa=r(Vi,"CODE",{});var ah=i(Wa);er=l(ah,"B-"),ah.forEach(s),tr=l(Vi," label for the first word and an "),Ga=r(Vi,"CODE",{});var lh=i(Ga);sr=l(lh,"I-"),lh.forEach(s),ar=l(Vi," label for the second."),Vi.forEach(s),on=h(e),E(at.$$.fragment,e),Bs=h(e),Zt=r(e,"H3",{class:!0});var Ip=i(Zt);Et=r(Ip,"A",{id:!0,class:!0,href:!0});var nh=i(Et);rn=r(nh,"SPAN",{});var oh=i(rn);E(Ms.$$.fragment,oh),oh.forEach(s),nh.forEach(s),lr=h(Ip),$l=r(Ip,"SPAN",{});var rh=i($l);ms=l(rh,"Processing the data"),rh.forEach(s),Ip.forEach(s),Vn=h(e),E(Hs.$$.fragment,e),Jn=h(e),_s=r(e,"P",{});var Ji=i(_s);pn=l(Ji,"As usual, our texts need to be converted to token IDs before the model can make sense of them. As we saw in "),yl=r(Ji,"A",{href:!0});var ih=i(yl);nr=l(ih,"Chapter 6"),ih.forEach(s),Qn=l(Ji,", a big difference in the case of token classification tasks is that we have pre-tokenized inputs. Fortunately, the tokenizer API can deal with that pretty easily; we just need to warn the "),Ws=r(Ji,"CODE",{});var ph=i(Ws);eo=l(ph,"tokenizer"),ph.forEach(s),jl=l(Ji," with a special flag."),Ji.forEach(s),to=h(e),Gs=r(e,"P",{});var Np=i(Gs);bs=l(Np,"To begin, let\u2019s create our "),Us=r(Np,"CODE",{});var ch=i(Us);or=l(ch,"tokenizer"),ch.forEach(s),cn=l(Np," object. As we said before, we will be using a BERT pretrained model, so we\u2019ll start by downloading and caching the associated tokenizer:"),Np.forEach(s),so=h(e),E(Ua.$$.fragment,e),ao=h(e),ae=r(e,"P",{});var Ca=i(ae);rr=l(Ca,"You can replace the "),Ya=r(Ca,"CODE",{});var hh=i(Ya);ir=l(hh,"model_checkpoint"),hh.forEach(s),pr=l(Ca," with any other model you prefer from the "),Ys=r(Ca,"A",{href:!0,rel:!0});var dh=i(Ys);cr=l(dh,"Hub"),dh.forEach(s),hr=l(Ca,", or with a local folder in which you\u2019ve saved a pretrained model and a tokenizer. The only constraint is that the tokenizer needs to be backed by the \u{1F917} Tokenizers library, so there\u2019s a \u201Cfast\u201D version available. You can see all the architectures that come with a fast version in "),Xs=r(Ca,"A",{href:!0,rel:!0});var uh=i(Xs);dr=l(uh,"this big table"),uh.forEach(s),ur=l(Ca,", and to check that the "),Xa=r(Ca,"CODE",{});var fh=i(Xa);fr=l(fh,"tokenizer"),fh.forEach(s),mr=l(Ca," object you\u2019re using is indeed backed by \u{1F917} Tokenizers you can look at its "),hn=r(Ca,"CODE",{});var mh=i(hn);Zs=l(mh,"is_fast"),mh.forEach(s),_r=l(Ca," attribute:"),Ca.forEach(s),El=h(e),E(Za.$$.fragment,e),lo=h(e),E(Ks.$$.fragment,e),no=h(e),ws=r(e,"P",{});var Qi=i(ws);oo=l(Qi,"To tokenize a pre-tokenized input, we can use our "),va=r(Qi,"CODE",{});var _h=i(va);br=l(_h,"tokenizer"),_h.forEach(s),ro=l(Qi," as usual and just add "),Vs=r(Qi,"CODE",{});var bh=i(Vs);io=l(bh,"is_split_into_words=True"),bh.forEach(s),xl=l(Qi,":"),Qi.forEach(s),po=h(e),E(ka.$$.fragment,e),$a=h(e),E(ya.$$.fragment,e),he=h(e),Ne=r(e,"P",{});var Ta=i(Ne);dn=l(Ta,"As we can see, the tokenizer added the special tokens used by the model ("),un=r(Ta,"CODE",{});var wh=i(un);wr=l(wh,"[CLS]"),wh.forEach(s),fn=l(Ta," at the beginning and "),mn=r(Ta,"CODE",{});var gh=i(mn);gr=l(gh,"[SEP]"),gh.forEach(s),_n=l(Ta," at the end) and left most of the words untouched. The word "),bn=r(Ta,"CODE",{});var vh=i(bn);vr=l(vh,"lamb"),vh.forEach(s),wn=l(Ta,", however, was tokenized into two subwords, "),gn=r(Ta,"CODE",{});var kh=i(gn);kr=l(kh,"la"),kh.forEach(s),vn=l(Ta," and "),kn=r(Ta,"CODE",{});var $h=i(kn);$r=l($h,"##mb"),$h.forEach(s),$n=l(Ta,". This introduces a mismatch between our inputs and the labels: the list of labels has only 9 elements, whereas our input now has 12 tokens. Accounting for the special tokens is easy (we know they are at the beginning and the end), but we also need to make sure we align all the labels with the proper words."),Ta.forEach(s),co=h(e),ja=r(e,"P",{});var Sp=i(ja);yn=l(Sp,"Fortunately, because we\u2019re using a fast tokenizer we have access to the \u{1F917} Tokenizers superpowers, which means we can easily map each token to its corresponding word (as seen in "),Ol=r(Sp,"A",{href:!0});var yh=i(Ol);yr=l(yh,"Chapter 6"),yh.forEach(s),ho=l(Sp,"):"),Sp.forEach(s),Kt=h(e),E(Ka.$$.fragment,e),Cl=h(e),E(Va.$$.fragment,e),uo=h(e),$e=r(e,"P",{});var Ul=i($e);jn=l(Ul,"With a tiny bit of work, we can then expand our label list to match the tokens. The first rule we\u2019ll apply is that special tokens get a label of "),En=r(Ul,"CODE",{});var jh=i(En);jr=l(jh,"-100"),jh.forEach(s),fo=l(Ul,". This is because by default "),n=r(Ul,"CODE",{});var Eh=i(n);_=l(Eh,"-100"),Eh.forEach(s),ii=l(Ul," is an index that is ignored in the loss function we will use (cross entropy). Then, each token gets the same label as the token that started the word it\u2019s inside, since they are part of the same entity. For tokens inside a word but not at the beginning, we replace the "),mo=r(Ul,"CODE",{});var xh=i(mo);pi=l(xh,"B-"),xh.forEach(s),Tl=l(Ul," with "),_o=r(Ul,"CODE",{});var Oh=i(_o);ci=l(Oh,"I-"),Oh.forEach(s),Dl=l(Ul," (since the token does not begin the entity):"),Ul.forEach(s),Er=h(e),E(Pl.$$.fragment,e),xn=h(e),On=r(e,"P",{});var Ch=i(On);zl=l(Ch,"Let\u2019s try it out on our first sentence:"),Ch.forEach(s),xr=h(e),E(ql.$$.fragment,e),Cn=h(e),E(Al.$$.fragment,e),Or=h(e),Js=r(e,"P",{});var ep=i(Js);bo=l(ep,"As we can see, our function added the "),wo=r(ep,"CODE",{});var Th=i(wo);hi=l(Th,"-100"),Th.forEach(s),di=l(ep," for the two special tokens at the beginning and the end, and a new "),Il=r(ep,"CODE",{});var Dh=i(Il);ui=l(Dh,"0"),Dh.forEach(s),lt=l(ep," for our word that was split into two tokens."),ep.forEach(s),Cr=h(e),E(Ja.$$.fragment,e),go=h(e),ht=r(e,"P",{});var Yl=i(ht);fi=l(Yl,"To preprocess our whole dataset, we need to tokenize all the inputs and apply "),vo=r(Yl,"CODE",{});var Ph=i(vo);mi=l(Ph,"align_labels_with_tokens()"),Ph.forEach(s),ko=l(Yl," on all the labels. To take advantage of the speed of our fast tokenizer, it\u2019s best to tokenize lots of texts at the same time, so we\u2019ll write a function that processes a list of examples and use the "),$o=r(Yl,"CODE",{});var zh=i($o);_i=l(zh,"Dataset.map()"),zh.forEach(s),yo=l(Yl," method with the option "),jo=r(Yl,"CODE",{});var qh=i(jo);bi=l(qh,"batched=True"),qh.forEach(s),Eo=l(Yl,". The only thing that is different from our previous example is that the "),xo=r(Yl,"CODE",{});var Ah=i(xo);wi=l(Ah,"word_ids()"),Ah.forEach(s),Oo=l(Yl," function needs to get the index of the example we want the word IDs of when the inputs to the tokenizer are lists of texts (or in our case, list of lists of words), so we add that too:"),Yl.forEach(s),Tr=h(e),E(Nl.$$.fragment,e),Dr=h(e),Qa=r(e,"P",{});var Ih=i(Qa);gi=l(Ih,"Note that we haven\u2019t padded our inputs yet; we\u2019ll do that later, when creating the batches with a data collator."),Ih.forEach(s),Tn=h(e),Dn=r(e,"P",{});var Nh=i(Dn);vi=l(Nh,"We can now apply all that preprocessing in one go on the other splits of our dataset:"),Nh.forEach(s),Pr=h(e),E(xt.$$.fragment,e),zr=h(e),el=r(e,"P",{});var Fp=i(el);ki=l(Fp,"We\u2019ve done the hardest part! Now that the data has been preprocessed, the actual training will look a lot like what we did in "),Pn=r(Fp,"A",{href:!0});var Sh=i(Pn);Sl=l(Sh,"Chapter 3"),Sh.forEach(s),$i=l(Fp,"."),Fp.forEach(s),qr=h(e),gs.l(e),Qs=h(e),Ea=r(e,"H3",{class:!0});var Lp=i(Ea);tl=r(Lp,"A",{id:!0,class:!0,href:!0});var Fh=i(tl);vs=r(Fh,"SPAN",{});var Lh=i(vs);E(Fl.$$.fragment,Lh),Lh.forEach(s),Fh.forEach(s),yi=h(Lp),Co=r(Lp,"SPAN",{});var Rh=i(Co);ji=l(Rh,"Data collation"),Rh.forEach(s),Lp.forEach(s),sl=h(e),Vt=r(e,"P",{});var Io=i(Vt);Ei=l(Io,"We can\u2019t just use a "),Ll=r(Io,"CODE",{});var Bh=i(Ll);xi=l(Bh,"DataCollatorWithPadding"),Bh.forEach(s),Oi=l(Io," like in "),zn=r(Io,"A",{href:!0});var Mh=i(zn);Rl=l(Mh,"Chapter 3"),Mh.forEach(s),Ci=l(Io," because that only pads the inputs (input IDs, attention mask, and token type IDs). Here our labels should be padded the exact same way as the inputs so that they stay the same size, using "),To=r(Io,"CODE",{});var Hh=i(To);Ti=l(Hh,"-100"),Hh.forEach(s),Bl=l(Io," as a value so that the corresponding predictions are ignored in the loss computation."),Io.forEach(s),qn=h(e),Jt=r(e,"P",{});var No=i(Jt);ks=l(No,"This is all done by a "),Ml=r(No,"A",{href:!0,rel:!0});var Wh=i(Ml);Do=r(Wh,"CODE",{});var Gh=i(Do);Di=l(Gh,"DataCollatorForTokenClassification"),Gh.forEach(s),Wh.forEach(s),Pi=l(No,". Like the "),xa=r(No,"CODE",{});var Uh=i(xa);zi=l(Uh,"DataCollatorWithPadding"),Uh.forEach(s),qi=l(No,", it takes the "),Po=r(No,"CODE",{});var Yh=i(Po);Ai=l(Yh,"tokenizer"),Yh.forEach(s),Se=l(No," used to preprocess the inputs:"),No.forEach(s),Ar=h(e),ys.l(e),An=h(e),In=r(e,"P",{});var Xh=i(In);Ii=l(Xh,"To test this on a few samples, we can just call it on a list of examples from our tokenized training set:"),Xh.forEach(s),Ir=h(e),E(js.$$.fragment,e),Nr=h(e),E(Hl.$$.fragment,e),Sr=h(e),Ni=r(e,"P",{});var Zh=i(Ni);Hp=l(Zh,"Let\u2019s compare this to the labels for the first and second elements in our dataset:"),Zh.forEach(s),pp=h(e),E(Fr.$$.fragment,e),cp=h(e),E(Lr.$$.fragment,e),hp=h(e),ll.l(e),Si=h(e),Ge&&Ge.l(e),Fi=h(e),Nn=r(e,"H3",{class:!0});var Rp=i(Nn);zo=r(Rp,"A",{id:!0,class:!0,href:!0});var Kh=i(zo);tp=r(Kh,"SPAN",{});var Vh=i(tp);E(Rr.$$.fragment,Vh),Vh.forEach(s),Kh.forEach(s),Wp=h(Rp),sp=r(Rp,"SPAN",{});var Jh=i(sp);Gp=l(Jh,"Metrics"),Jh.forEach(s),Rp.forEach(s),dp=h(e),ol.l(e),Li=h(e),E(Br.$$.fragment,e),up=h(e),Ri=r(e,"P",{});var Qh=i(Ri);Up=l(Qh,"This metric does not behave like the standard accuracy: it will actually take the lists of labels as strings, not integers, so we will need to fully decode the predictions and labels before passing them to the metric. Let\u2019s see how it works. First, we\u2019ll get the labels for our first training example:"),Qh.forEach(s),fp=h(e),E(Mr.$$.fragment,e),mp=h(e),E(Hr.$$.fragment,e),_p=h(e),Bi=r(e,"P",{});var ed=i(Bi);Yp=l(ed,"We can then create fake predictions for those by just changing the value at index 2:"),ed.forEach(s),bp=h(e),E(Wr.$$.fragment,e),wp=h(e),Mi=r(e,"P",{});var td=i(Mi);Xp=l(td,"Note that the metric takes a list of predictions (not just one) and a list of labels. Here\u2019s the output:"),td.forEach(s),gp=h(e),E(Gr.$$.fragment,e),vp=h(e),il.l(e),Hi=h(e),Ue&&Ue.l(e),Wi=h(e),Sn=r(e,"H2",{class:!0});var Bp=i(Sn);qo=r(Bp,"A",{id:!0,class:!0,href:!0});var sd=i(qo);ap=r(sd,"SPAN",{});var ad=i(ap);E(Ur.$$.fragment,ad),ad.forEach(s),sd.forEach(s),Zp=h(Bp),lp=r(Bp,"SPAN",{});var ld=i(lp);Kp=l(ld,"Using the fine-tuned model"),ld.forEach(s),Bp.forEach(s),kp=h(e),Ao=r(e,"P",{});var Mp=i(Ao);Vp=l(Mp,"We\u2019ve already shown you how you can use the model we fine-tuned on the Model Hub with the inference widget. To use it locally in a "),np=r(Mp,"CODE",{});var nd=i(np);Jp=l(nd,"pipeline"),nd.forEach(s),Qp=l(Mp,", you just have to specify the proper model identifier:"),Mp.forEach(s),$p=h(e),E(Yr.$$.fragment,e),yp=h(e),E(Xr.$$.fragment,e),jp=h(e),Gi=r(e,"P",{});var od=i(Gi);ec=l(od,"Great! Our model is working as well as the default one for this pipeline!"),od.forEach(s),this.h()},h(){k(d,"name","hf:doc:metadata"),k(d,"content",JSON.stringify(Ld)),k(v,"id","token-classification"),k(v,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(v,"href","#token-classification"),k(T,"class","relative group"),sc(fe.src,Ye="https://hf.space/gradioiframe/course-demos/bert-finetuned-ner/+")||k(fe,"src",Ye),k(fe,"frameborder","0"),k(fe,"height","350"),k(fe,"title","Gradio app"),k(fe,"class","block dark:hidden container p-0 flex-grow space-iframe"),k(fe,"allow","accelerometer; ambient-light-sensor; autoplay; battery; camera; document-domain; encrypted-media; fullscreen; geolocation; gyroscope; layout-animations; legacy-image-formats; magnetometer; microphone; midi; oversized-images; payment; picture-in-picture; publickey-credentials-get; sync-xhr; usb; vr ; wake-lock; xr-spatial-tracking"),k(fe,"sandbox","allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-downloads"),k(ce,"class","block dark:hidden lg:w-3/5"),sc(ce.src,ss="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter7/model-eval-bert-finetuned-ner.png")||k(ce,"src",ss),k(ce,"alt","One-hot encoded labels for question answering."),k(Dt,"class","hidden dark:block lg:w-3/5"),sc(Dt.src,as="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter7/model-eval-bert-finetuned-ner-dark.png")||k(Dt,"src",as),k(Dt,"alt","One-hot encoded labels for question answering."),k(se,"class","flex justify-center"),k(se,"href","/huggingface-course/bert-finetuned-ner"),k(Pt,"href","https://huggingface.co/huggingface-course/bert-finetuned-ner?text=My+name+is+Sylvain+and+I+work+at+Hugging+Face+in+Brooklyn"),k(Pt,"rel","nofollow"),k(De,"id","preparing-the-data"),k(De,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(De,"href","#preparing-the-data"),k(je,"class","relative group"),k(Ke,"href","https://huggingface.co/datasets/conll2003"),k(Ke,"rel","nofollow"),k(ze,"id","the-conll2003-dataset"),k(ze,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(ze,"href","#the-conll2003-dataset"),k(Pe,"class","relative group"),k(os,"href","/course/chapter3"),k(ke,"href","/course/chapter6/3"),k(Et,"id","processing-the-data"),k(Et,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(Et,"href","#processing-the-data"),k(Zt,"class","relative group"),k(yl,"href","/course/chapter6/"),k(Ys,"href","https://huggingface.co/models"),k(Ys,"rel","nofollow"),k(Xs,"href","https://huggingface.co/transformers/#supported-frameworks"),k(Xs,"rel","nofollow"),k(Ol,"href","/course/chapter6/3"),k(Pn,"href","/course/chapter3"),k(tl,"id","data-collation"),k(tl,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(tl,"href","#data-collation"),k(Ea,"class","relative group"),k(zn,"href","/course/chapter3"),k(Ml,"href","https://huggingface.co/transformers/main_classes/data_collator.html#datacollatorfortokenclassification"),k(Ml,"rel","nofollow"),k(zo,"id","metrics"),k(zo,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(zo,"href","#metrics"),k(Nn,"class","relative group"),k(qo,"id","using-the-finetuned-model"),k(qo,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),k(qo,"href","#using-the-finetuned-model"),k(Sn,"class","relative group")},m(e,u){t(document.head,d),p(e,g,u),x(m,e,u),p(e,$,u),p(e,T,u),t(T,v),t(v,y),x(D,y,null),t(T,z),t(T,N),t(N,B),p(e,A,u),Zr[I].m(e,u),p(e,G,u),p(e,Z,u),t(Z,X),p(e,C,u),p(e,S,u),t(S,P),t(P,H),t(H,F),t(P,Y),t(S,Q),t(S,ee),t(ee,oe),t(oe,K),t(ee,de),t(S,J),t(S,W),t(W,R),t(R,le),t(W,ue),t(W,ye),t(ye,ne),t(W,Fe),t(W,V),t(V,nt),t(W,pe),t(W,dt),t(dt,Qt),t(W,ot),p(e,ea,u),x(Tt,e,u),p(e,es,u),p(e,we,u),t(we,Es),p(e,Te,u),p(e,fe,u),p(e,ts,u),p(e,se,u),t(se,ce),t(se,Le),t(se,Dt),p(e,ta,u),p(e,Xe,u),t(Xe,Re),t(Xe,Pt),t(Pt,ls),t(Xe,zt),p(e,xs,u),p(e,je,u),t(je,De),t(De,qt),x(Ee,qt,null),t(je,Da),t(je,At),t(At,Ze),p(e,Os,u),p(e,ie,u),t(ie,It),t(ie,Ke),t(Ke,ut),t(ie,Pa),p(e,ft,u),x(mt,e,u),p(e,sa,u),p(e,Pe,u),t(Pe,ze),t(ze,ns),x(te,ns,null),t(Pe,Nt),t(Pe,_t),t(_t,Ve),p(e,aa,u),p(e,qe,u),t(qe,za),t(qe,Cs),t(Cs,Je),t(qe,Ts),p(e,la,u),x(bt,e,u),p(e,rt,u),p(e,Qe,u),t(Qe,Ds),t(Qe,os),t(os,Ps),t(Qe,na),p(e,wt,u),x(et,e,u),p(e,me,u),x(St,e,u),p(e,Ft,u),p(e,Ae,u),t(Ae,oa),t(Ae,_e),t(_e,zs),t(Ae,qs),p(e,ra,u),p(e,rs,u),t(rs,is),p(e,gt,u),x(vt,e,u),p(e,it,u),x(Lt,e,u),p(e,As,u),p(e,Ie,u),t(Ie,Rt),p(e,Bt,u),x(tt,e,u),p(e,ia,u),x(pt,e,u),p(e,Be,u),p(e,ct,u),t(ct,Mt),t(ct,f),t(f,L),t(ct,ps),p(e,pa,u),x(Me,e,u),p(e,Ht,u),x(kt,e,u),p(e,qa,u),p(e,re,u),t(re,Aa),t(re,Wt),t(Wt,ca),t(re,Ia),t(re,ge),t(ge,Gt),t(re,ha),t(re,st),t(st,pl),t(re,da),t(re,ua),t(ua,Na),t(re,Ut),t(re,fa),t(fa,He),t(re,cl),p(e,Sa,u),x(Yt,e,u),p(e,xe,u),x(We,e,u),p(e,Is,u),p(e,be,u),t(be,hl),t(be,ve),t(ve,dl),t(be,ma),t(be,ke),t(ke,ul),t(be,_a),p(e,Fa,u),p(e,Oe,u),t(Oe,ba),t(ba,Xl),t(Xl,Ro),t(ba,Zl),t(Oe,Bo),t(Oe,cs),t(cs,fl),t(fl,La),t(cs,Ln),t(cs,wa),t(wa,Mo),t(cs,Rn),t(cs,Ns),t(Ns,Bn),t(cs,hs),t(Oe,Ho),t(Oe,$t),t($t,Kl),t(Kl,Wo),t($t,Vl),t($t,Jl),t(Jl,Go),t($t,Mn),t($t,Ss),t(Ss,Hn),t($t,ga),t(Oe,Uo),t(Oe,yt),t(yt,Ql),t(Ql,Yo),t(yt,Wn),t(yt,Fs),t(Fs,Gn),t(yt,Ra),t(yt,ml),t(ml,ds),t(yt,Xo),t(Oe,en),t(Oe,us),t(us,tn),t(tn,sn),t(us,Zo),t(us,an),t(an,Un),t(us,Ba),t(us,_l),t(_l,jt),t(us,Ko),p(e,bl,u),p(e,wl,u),t(wl,Vo),p(e,gl,u),x(Ma,e,u),p(e,Yn,u),x(Ls,e,u),p(e,Xn,u),p(e,fs,u),t(fs,Zn),t(fs,Rs),t(Rs,Kn),t(fs,Ha),t(fs,vl),t(vl,kl),t(fs,Jo),p(e,ln,u),x(Xt,e,u),p(e,nn,u),p(e,Ce,u),t(Ce,Qo),t(Ce,Wa),t(Wa,er),t(Ce,tr),t(Ce,Ga),t(Ga,sr),t(Ce,ar),p(e,on,u),x(at,e,u),p(e,Bs,u),p(e,Zt,u),t(Zt,Et),t(Et,rn),x(Ms,rn,null),t(Zt,lr),t(Zt,$l),t($l,ms),p(e,Vn,u),x(Hs,e,u),p(e,Jn,u),p(e,_s,u),t(_s,pn),t(_s,yl),t(yl,nr),t(_s,Qn),t(_s,Ws),t(Ws,eo),t(_s,jl),p(e,to,u),p(e,Gs,u),t(Gs,bs),t(Gs,Us),t(Us,or),t(Gs,cn),p(e,so,u),x(Ua,e,u),p(e,ao,u),p(e,ae,u),t(ae,rr),t(ae,Ya),t(Ya,ir),t(ae,pr),t(ae,Ys),t(Ys,cr),t(ae,hr),t(ae,Xs),t(Xs,dr),t(ae,ur),t(ae,Xa),t(Xa,fr),t(ae,mr),t(ae,hn),t(hn,Zs),t(ae,_r),p(e,El,u),x(Za,e,u),p(e,lo,u),x(Ks,e,u),p(e,no,u),p(e,ws,u),t(ws,oo),t(ws,va),t(va,br),t(ws,ro),t(ws,Vs),t(Vs,io),t(ws,xl),p(e,po,u),x(ka,e,u),p(e,$a,u),x(ya,e,u),p(e,he,u),p(e,Ne,u),t(Ne,dn),t(Ne,un),t(un,wr),t(Ne,fn),t(Ne,mn),t(mn,gr),t(Ne,_n),t(Ne,bn),t(bn,vr),t(Ne,wn),t(Ne,gn),t(gn,kr),t(Ne,vn),t(Ne,kn),t(kn,$r),t(Ne,$n),p(e,co,u),p(e,ja,u),t(ja,yn),t(ja,Ol),t(Ol,yr),t(ja,ho),p(e,Kt,u),x(Ka,e,u),p(e,Cl,u),x(Va,e,u),p(e,uo,u),p(e,$e,u),t($e,jn),t($e,En),t(En,jr),t($e,fo),t($e,n),t(n,_),t($e,ii),t($e,mo),t(mo,pi),t($e,Tl),t($e,_o),t(_o,ci),t($e,Dl),p(e,Er,u),x(Pl,e,u),p(e,xn,u),p(e,On,u),t(On,zl),p(e,xr,u),x(ql,e,u),p(e,Cn,u),x(Al,e,u),p(e,Or,u),p(e,Js,u),t(Js,bo),t(Js,wo),t(wo,hi),t(Js,di),t(Js,Il),t(Il,ui),t(Js,lt),p(e,Cr,u),x(Ja,e,u),p(e,go,u),p(e,ht,u),t(ht,fi),t(ht,vo),t(vo,mi),t(ht,ko),t(ht,$o),t($o,_i),t(ht,yo),t(ht,jo),t(jo,bi),t(ht,Eo),t(ht,xo),t(xo,wi),t(ht,Oo),p(e,Tr,u),x(Nl,e,u),p(e,Dr,u),p(e,Qa,u),t(Qa,gi),p(e,Tn,u),p(e,Dn,u),t(Dn,vi),p(e,Pr,u),x(xt,e,u),p(e,zr,u),p(e,el,u),t(el,ki),t(el,Pn),t(Pn,Sl),t(el,$i),p(e,qr,u),Kr[Ot].m(e,u),p(e,Qs,u),p(e,Ea,u),t(Ea,tl),t(tl,vs),x(Fl,vs,null),t(Ea,yi),t(Ea,Co),t(Co,ji),p(e,sl,u),p(e,Vt,u),t(Vt,Ei),t(Vt,Ll),t(Ll,xi),t(Vt,Oi),t(Vt,zn),t(zn,Rl),t(Vt,Ci),t(Vt,To),t(To,Ti),t(Vt,Bl),p(e,qn,u),p(e,Jt,u),t(Jt,ks),t(Jt,Ml),t(Ml,Do),t(Do,Di),t(Jt,Pi),t(Jt,xa),t(xa,zi),t(Jt,qi),t(Jt,Po),t(Po,Ai),t(Jt,Se),p(e,Ar,u),Vr[$s].m(e,u),p(e,An,u),p(e,In,u),t(In,Ii),p(e,Ir,u),x(js,e,u),p(e,Nr,u),x(Hl,e,u),p(e,Sr,u),p(e,Ni,u),t(Ni,Hp),p(e,pp,u),x(Fr,e,u),p(e,cp,u),x(Lr,e,u),p(e,hp,u),Jr[al].m(e,u),p(e,Si,u),Ge&&Ge.m(e,u),p(e,Fi,u),p(e,Nn,u),t(Nn,zo),t(zo,tp),x(Rr,tp,null),t(Nn,Wp),t(Nn,sp),t(sp,Gp),p(e,dp,u),Qr[nl].m(e,u),p(e,Li,u),x(Br,e,u),p(e,up,u),p(e,Ri,u),t(Ri,Up),p(e,fp,u),x(Mr,e,u),p(e,mp,u),x(Hr,e,u),p(e,_p,u),p(e,Bi,u),t(Bi,Yp),p(e,bp,u),x(Wr,e,u),p(e,wp,u),p(e,Mi,u),t(Mi,Xp),p(e,gp,u),x(Gr,e,u),p(e,vp,u),ei[rl].m(e,u),p(e,Hi,u),Ue&&Ue.m(e,u),p(e,Wi,u),p(e,Sn,u),t(Sn,qo),t(qo,ap),x(Ur,ap,null),t(Sn,Zp),t(Sn,lp),t(lp,Kp),p(e,kp,u),p(e,Ao,u),t(Ao,Vp),t(Ao,np),t(np,Jp),t(Ao,Qp),p(e,$p,u),x(Yr,e,u),p(e,yp,u),x(Xr,e,u),p(e,jp,u),p(e,Gi,u),t(Gi,ec),Ep=!0},p(e,[u]){const ti={};u&1&&(ti.fw=e[0]),m.$set(ti);let Ui=I;I=lc(e),I!==Ui&&(Fo(),w(Zr[Ui],1,1,()=>{Zr[Ui]=null}),So(),M=Zr[I],M||(M=Zr[I]=ac[I](e),M.c()),b(M,1),M.m(G.parentNode,G));const op={};u&2&&(op.$$scope={dirty:u,ctx:e}),mt.$set(op);const rp={};u&2&&(rp.$$scope={dirty:u,ctx:e}),at.$set(rp);const ip={};u&2&&(ip.$$scope={dirty:u,ctx:e}),Ja.$set(ip);let Wl=Ot;Ot=oc(e),Ot!==Wl&&(Fo(),w(Kr[Wl],1,1,()=>{Kr[Wl]=null}),So(),gs=Kr[Ot],gs||(gs=Kr[Ot]=nc[Ot](e),gs.c()),b(gs,1),gs.m(Qs.parentNode,Qs));let si=$s;$s=ic(e),$s!==si&&(Fo(),w(Vr[si],1,1,()=>{Vr[si]=null}),So(),ys=Vr[$s],ys||(ys=Vr[$s]=rc[$s](e),ys.c()),b(ys,1),ys.m(An.parentNode,An));let Yi=al;al=cc(e),al!==Yi&&(Fo(),w(Jr[Yi],1,1,()=>{Jr[Yi]=null}),So(),ll=Jr[al],ll||(ll=Jr[al]=pc[al](e),ll.c()),b(ll,1),ll.m(Si.parentNode,Si)),e[0]==="tf"?Ge?u&1&&b(Ge,1):(Ge=pd(e),Ge.c(),b(Ge,1),Ge.m(Fi.parentNode,Fi)):Ge&&(Fo(),w(Ge,1,1,()=>{Ge=null}),So());let ai=nl;nl=dc(e),nl!==ai&&(Fo(),w(Qr[ai],1,1,()=>{Qr[ai]=null}),So(),ol=Qr[nl],ol||(ol=Qr[nl]=hc[nl](e),ol.c()),b(ol,1),ol.m(Li.parentNode,Li));let Xi=rl;rl=fc(e),rl!==Xi&&(Fo(),w(ei[Xi],1,1,()=>{ei[Xi]=null}),So(),il=ei[rl],il||(il=ei[rl]=uc[rl](e),il.c()),b(il,1),il.m(Hi.parentNode,Hi)),e[0]==="pt"?Ue?u&1&&b(Ue,1):(Ue=cd(e),Ue.c(),b(Ue,1),Ue.m(Wi.parentNode,Wi)):Ue&&(Fo(),w(Ue,1,1,()=>{Ue=null}),So())},i(e){Ep||(b(m.$$.fragment,e),b(D.$$.fragment,e),b(M),b(Tt.$$.fragment,e),b(Ee.$$.fragment,e),b(mt.$$.fragment,e),b(te.$$.fragment,e),b(bt.$$.fragment,e),b(et.$$.fragment,e),b(St.$$.fragment,e),b(vt.$$.fragment,e),b(Lt.$$.fragment,e),b(tt.$$.fragment,e),b(pt.$$.fragment,e),b(Me.$$.fragment,e),b(kt.$$.fragment,e),b(Yt.$$.fragment,e),b(We.$$.fragment,e),b(Ma.$$.fragment,e),b(Ls.$$.fragment,e),b(Xt.$$.fragment,e),b(at.$$.fragment,e),b(Ms.$$.fragment,e),b(Hs.$$.fragment,e),b(Ua.$$.fragment,e),b(Za.$$.fragment,e),b(Ks.$$.fragment,e),b(ka.$$.fragment,e),b(ya.$$.fragment,e),b(Ka.$$.fragment,e),b(Va.$$.fragment,e),b(Pl.$$.fragment,e),b(ql.$$.fragment,e),b(Al.$$.fragment,e),b(Ja.$$.fragment,e),b(Nl.$$.fragment,e),b(xt.$$.fragment,e),b(gs),b(Fl.$$.fragment,e),b(ys),b(js.$$.fragment,e),b(Hl.$$.fragment,e),b(Fr.$$.fragment,e),b(Lr.$$.fragment,e),b(ll),b(Ge),b(Rr.$$.fragment,e),b(ol),b(Br.$$.fragment,e),b(Mr.$$.fragment,e),b(Hr.$$.fragment,e),b(Wr.$$.fragment,e),b(Gr.$$.fragment,e),b(il),b(Ue),b(Ur.$$.fragment,e),b(Yr.$$.fragment,e),b(Xr.$$.fragment,e),Ep=!0)},o(e){w(m.$$.fragment,e),w(D.$$.fragment,e),w(M),w(Tt.$$.fragment,e),w(Ee.$$.fragment,e),w(mt.$$.fragment,e),w(te.$$.fragment,e),w(bt.$$.fragment,e),w(et.$$.fragment,e),w(St.$$.fragment,e),w(vt.$$.fragment,e),w(Lt.$$.fragment,e),w(tt.$$.fragment,e),w(pt.$$.fragment,e),w(Me.$$.fragment,e),w(kt.$$.fragment,e),w(Yt.$$.fragment,e),w(We.$$.fragment,e),w(Ma.$$.fragment,e),w(Ls.$$.fragment,e),w(Xt.$$.fragment,e),w(at.$$.fragment,e),w(Ms.$$.fragment,e),w(Hs.$$.fragment,e),w(Ua.$$.fragment,e),w(Za.$$.fragment,e),w(Ks.$$.fragment,e),w(ka.$$.fragment,e),w(ya.$$.fragment,e),w(Ka.$$.fragment,e),w(Va.$$.fragment,e),w(Pl.$$.fragment,e),w(ql.$$.fragment,e),w(Al.$$.fragment,e),w(Ja.$$.fragment,e),w(Nl.$$.fragment,e),w(xt.$$.fragment,e),w(gs),w(Fl.$$.fragment,e),w(ys),w(js.$$.fragment,e),w(Hl.$$.fragment,e),w(Fr.$$.fragment,e),w(Lr.$$.fragment,e),w(ll),w(Ge),w(Rr.$$.fragment,e),w(ol),w(Br.$$.fragment,e),w(Mr.$$.fragment,e),w(Hr.$$.fragment,e),w(Wr.$$.fragment,e),w(Gr.$$.fragment,e),w(il),w(Ue),w(Ur.$$.fragment,e),w(Yr.$$.fragment,e),w(Xr.$$.fragment,e),Ep=!1},d(e){s(d),e&&s(g),O(m,e),e&&s($),e&&s(T),O(D),e&&s(A),Zr[I].d(e),e&&s(G),e&&s(Z),e&&s(C),e&&s(S),e&&s(ea),O(Tt,e),e&&s(es),e&&s(we),e&&s(Te),e&&s(fe),e&&s(ts),e&&s(se),e&&s(ta),e&&s(Xe),e&&s(xs),e&&s(je),O(Ee),e&&s(Os),e&&s(ie),e&&s(ft),O(mt,e),e&&s(sa),e&&s(Pe),O(te),e&&s(aa),e&&s(qe),e&&s(la),O(bt,e),e&&s(rt),e&&s(Qe),e&&s(wt),O(et,e),e&&s(me),O(St,e),e&&s(Ft),e&&s(Ae),e&&s(ra),e&&s(rs),e&&s(gt),O(vt,e),e&&s(it),O(Lt,e),e&&s(As),e&&s(Ie),e&&s(Bt),O(tt,e),e&&s(ia),O(pt,e),e&&s(Be),e&&s(ct),e&&s(pa),O(Me,e),e&&s(Ht),O(kt,e),e&&s(qa),e&&s(re),e&&s(Sa),O(Yt,e),e&&s(xe),O(We,e),e&&s(Is),e&&s(be),e&&s(Fa),e&&s(Oe),e&&s(bl),e&&s(wl),e&&s(gl),O(Ma,e),e&&s(Yn),O(Ls,e),e&&s(Xn),e&&s(fs),e&&s(ln),O(Xt,e),e&&s(nn),e&&s(Ce),e&&s(on),O(at,e),e&&s(Bs),e&&s(Zt),O(Ms),e&&s(Vn),O(Hs,e),e&&s(Jn),e&&s(_s),e&&s(to),e&&s(Gs),e&&s(so),O(Ua,e),e&&s(ao),e&&s(ae),e&&s(El),O(Za,e),e&&s(lo),O(Ks,e),e&&s(no),e&&s(ws),e&&s(po),O(ka,e),e&&s($a),O(ya,e),e&&s(he),e&&s(Ne),e&&s(co),e&&s(ja),e&&s(Kt),O(Ka,e),e&&s(Cl),O(Va,e),e&&s(uo),e&&s($e),e&&s(Er),O(Pl,e),e&&s(xn),e&&s(On),e&&s(xr),O(ql,e),e&&s(Cn),O(Al,e),e&&s(Or),e&&s(Js),e&&s(Cr),O(Ja,e),e&&s(go),e&&s(ht),e&&s(Tr),O(Nl,e),e&&s(Dr),e&&s(Qa),e&&s(Tn),e&&s(Dn),e&&s(Pr),O(xt,e),e&&s(zr),e&&s(el),e&&s(qr),Kr[Ot].d(e),e&&s(Qs),e&&s(Ea),O(Fl),e&&s(sl),e&&s(Vt),e&&s(qn),e&&s(Jt),e&&s(Ar),Vr[$s].d(e),e&&s(An),e&&s(In),e&&s(Ir),O(js,e),e&&s(Nr),O(Hl,e),e&&s(Sr),e&&s(Ni),e&&s(pp),O(Fr,e),e&&s(cp),O(Lr,e),e&&s(hp),Jr[al].d(e),e&&s(Si),Ge&&Ge.d(e),e&&s(Fi),e&&s(Nn),O(Rr),e&&s(dp),Qr[nl].d(e),e&&s(Li),O(Br,e),e&&s(up),e&&s(Ri),e&&s(fp),O(Mr,e),e&&s(mp),O(Hr,e),e&&s(_p),e&&s(Bi),e&&s(bp),O(Wr,e),e&&s(wp),e&&s(Mi),e&&s(gp),O(Gr,e),e&&s(vp),ei[rl].d(e),e&&s(Hi),Ue&&Ue.d(e),e&&s(Wi),e&&s(Sn),O(Ur),e&&s(kp),e&&s(Ao),e&&s($p),O(Yr,e),e&&s(yp),O(Xr,e),e&&s(jp),e&&s(Gi)}}}const Ld={local:"token-classification",sections:[{local:"preparing-the-data",sections:[{local:"the-conll2003-dataset",title:"The CoNLL-2003 dataset"},{local:"processing-the-data",title:"Processing the data"}],title:"Preparing the data"},{local:"finetuning-the-model-with-the-trainer-api",title:"Fine-tuning the model with the `Trainer` API"},{local:"finetuning-the-model-with-keras",sections:[{local:"data-collation",title:"Data collation"},{local:"defining-the-model",title:"Defining the model"},{local:"finetuning-the-model",title:"Fine-tuning the model"},{local:"metrics",title:"Metrics"},{local:"defining-the-model",title:"Defining the model"},{local:"finetuning-the-model",title:"Fine-tuning the model"}],title:"Fine-tuning the model with Keras"},{local:"a-custom-training-loop",sections:[{local:"preparing-everything-for-training",title:"Preparing everything for training"},{local:"training-loop",title:"Training loop"}],title:"A custom training loop"},{local:"using-the-finetuned-model",title:"Using the fine-tuned model"}],title:"Token classification"};function Rd(U,d,g){let m="pt";return _d(()=>{const $=new URLSearchParams(window.location.search);g(0,m=$.get("fw")||"pt")}),[m]}class Xd extends dd{constructor(d){super();ud(this,d,Rd,Fd,fd,{})}}export{Xd as default,Ld as metadata};
