import{S as dn,i as cn,s as hn,e as s,k as c,w,t as o,M as pn,c as i,d as a,m as h,x as v,a as n,h as r,b as u,G as t,g as d,y as _,q as g,o as $,B as E,v as un}from"../../chunks/vendor-hf-doc-builder.js";import{T as ln}from"../../chunks/Tip-hf-doc-builder.js";import{Y as fn}from"../../chunks/Youtube-hf-doc-builder.js";import{I as Ms}from"../../chunks/IconCopyLink-hf-doc-builder.js";import{C as F}from"../../chunks/CodeBlock-hf-doc-builder.js";import{C as mn}from"../../chunks/CourseFloatingBanner-hf-doc-builder.js";import{F as wn}from"../../chunks/FrameworkSwitchCourse-hf-doc-builder.js";function vn(ve){let p,A,f,x,T,b,k,q,B,te;return{c(){p=s("p"),A=o("\u{1F4A1} If you want to automatically upload your model to the Hub during training, pass along "),f=s("code"),x=o("push_to_hub=True"),T=o(" in the "),b=s("code"),k=o("TrainingArguments"),q=o(". We will learn more about this in "),B=s("a"),te=o("Chapter 4"),this.h()},l(ae){p=i(ae,"P",{});var z=n(p);A=r(z,"\u{1F4A1} If you want to automatically upload your model to the Hub during training, pass along "),f=i(z,"CODE",{});var Y=n(f);x=r(Y,"push_to_hub=True"),Y.forEach(a),T=r(z," in the "),b=i(z,"CODE",{});var _e=n(b);k=r(_e,"TrainingArguments"),_e.forEach(a),q=r(z,". We will learn more about this in "),B=i(z,"A",{href:!0});var J=n(B);te=r(J,"Chapter 4"),J.forEach(a),z.forEach(a),this.h()},h(){u(B,"href","/course/chapter4/3")},m(ae,z){d(ae,p,z),t(p,A),t(p,f),t(f,x),t(p,T),t(p,b),t(b,k),t(p,q),t(p,B),t(B,te)},d(ae){ae&&a(p)}}}function _n(ve){let p,A,f,x,T;return{c(){p=s("p"),A=o("\u270F\uFE0F "),f=s("strong"),x=o("Try it out!"),T=o(" Fine-tune a model on the GLUE SST-2 dataset, using the data processing you did in section 2.")},l(b){p=i(b,"P",{});var k=n(p);A=r(k,"\u270F\uFE0F "),f=i(k,"STRONG",{});var q=n(f);x=r(q,"Try it out!"),q.forEach(a),T=r(k," Fine-tune a model on the GLUE SST-2 dataset, using the data processing you did in section 2."),k.forEach(a)},m(b,k){d(b,p,k),t(p,A),t(p,f),t(f,x),t(p,T)},d(b){b&&a(p)}}}function gn(ve){let p,A,f,x,T,b,k,q,B,te,ae,z,Y,_e,J,sa,S,Xa,Qe,Ka,Qa,Ve,Va,Za,Ze,eo,to,ge,ao,oo,ia,We,ro,na,$e,la,oe,ie,et,Ee,so,tt,io,da,I,no,at,lo,co,ot,ho,po,rt,uo,fo,ca,be,ha,ne,pa,X,mo,Ue,wo,vo,st,_o,go,ua,ye,fa,le,$o,Ge,Eo,bo,ma,C,yo,it,To,ko,nt,Co,jo,lt,Oo,Po,dt,Do,Ao,ct,xo,qo,wa,Te,va,j,zo,ht,So,Fo,pt,Io,Wo,ut,Uo,Go,ft,Mo,No,mt,Lo,Ro,_a,K,Ho,wt,Bo,Yo,vt,Jo,Xo,ga,ke,$a,Me,Ko,Ea,de,D,Qo,_t,Vo,Zo,gt,er,tr,$t,ar,or,Et,rr,sr,bt,ir,nr,lr,re,dr,yt,cr,hr,Tt,pr,ur,ba,se,ce,kt,Ce,fr,Ct,mr,ya,O,wr,jt,vr,_r,Ot,gr,$r,Pt,Er,br,Dt,yr,Tr,At,kr,Cr,Ta,je,ka,Oe,Ca,m,jr,xt,Or,Pr,qt,Dr,Ar,zt,xr,qr,St,zr,Sr,Ft,Fr,Ir,It,Wr,Ur,Wt,Gr,Mr,Ut,Nr,Lr,ja,W,Rr,Gt,Hr,Br,Mt,Yr,Jr,Ne,Xr,Kr,Oa,Pe,Pa,P,Qr,Nt,Vr,Zr,Lt,es,ts,De,as,os,Rt,rs,ss,Ht,is,ns,Da,Ae,Aa,xe,xa,U,ls,qe,ds,cs,Bt,hs,ps,Yt,us,fs,qa,he,ms,Jt,ws,vs,za,ze,Sa,Q,_s,Xt,gs,$s,Kt,Es,bs,Fa,Se,Ia,G,ys,Qt,Ts,ks,Vt,Cs,js,Zt,Os,Ps,Wa,Fe,Ua,Le,Ds,Ga,V,As,ea,xs,qs,ta,zs,Ss,Ma,Z,Fs,aa,Is,Ws,Re,Us,Gs,Na,pe,La;return f=new wn({props:{fw:ve[0]}}),q=new Ms({}),Y=new mn({props:{chapter:3,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/chapter3/section3.ipynb"},{label:"Aws Studio",value:"https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/en/chapter3/section3.ipynb"}]}}),J=new fn({props:{id:"nvBXf7s7vTI"}}),$e=new F({props:{code:`from datasets import load_dataset
from transformers import AutoTokenizer, DataCollatorWithPadding

raw_datasets = load_dataset("glue", "mrpc")
checkpoint = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)


def tokenize_function(example):
    return tokenizer(example["sentence1"], example["sentence2"], truncation=True)


tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)`,highlighted:`<span class="hljs-keyword">from</span> datasets <span class="hljs-keyword">import</span> load_dataset
<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoTokenizer, DataCollatorWithPadding

raw_datasets = load_dataset(<span class="hljs-string">&quot;glue&quot;</span>, <span class="hljs-string">&quot;mrpc&quot;</span>)
checkpoint = <span class="hljs-string">&quot;bert-base-uncased&quot;</span>
tokenizer = AutoTokenizer.from_pretrained(checkpoint)


<span class="hljs-keyword">def</span> <span class="hljs-title function_">tokenize_function</span>(<span class="hljs-params">example</span>):
    <span class="hljs-keyword">return</span> tokenizer(example[<span class="hljs-string">&quot;sentence1&quot;</span>], example[<span class="hljs-string">&quot;sentence2&quot;</span>], truncation=<span class="hljs-literal">True</span>)


tokenized_datasets = raw_datasets.<span class="hljs-built_in">map</span>(tokenize_function, batched=<span class="hljs-literal">True</span>)
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)`}}),Ee=new Ms({}),be=new F({props:{code:`from transformers import TrainingArguments

training_args = TrainingArguments("test-trainer")`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> TrainingArguments

training_args = TrainingArguments(<span class="hljs-string">&quot;test-trainer&quot;</span>)`}}),ne=new ln({props:{$$slots:{default:[vn]},$$scope:{ctx:ve}}}),ye=new F({props:{code:`from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=<span class="hljs-number">2</span>)`}}),Te=new F({props:{code:`from transformers import Trainer

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

trainer = Trainer(
    model,
    training_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,
    tokenizer=tokenizer,
)`}}),ke=new F({props:{code:"trainer.train()",highlighted:"trainer.train()"}}),Ce=new Ms({}),je=new F({props:{code:`predictions = trainer.predict(tokenized_datasets["validation"])
print(predictions.predictions.shape, predictions.label_ids.shape)`,highlighted:`predictions = trainer.predict(tokenized_datasets[<span class="hljs-string">&quot;validation&quot;</span>])
<span class="hljs-built_in">print</span>(predictions.predictions.shape, predictions.label_ids.shape)`}}),Oe=new F({props:{code:"(408, 2) (408,)",highlighted:'(<span class="hljs-number">408</span>, <span class="hljs-number">2</span>) (<span class="hljs-number">408</span>,)'}}),Pe=new F({props:{code:`import numpy as np

preds = np.argmax(predictions.predictions, axis=-1)`,highlighted:`<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np

preds = np.argmax(predictions.predictions, axis=-<span class="hljs-number">1</span>)`}}),Ae=new F({props:{code:`import evaluate

metric = evaluate.load("glue", "mrpc")
metric.compute(predictions=preds, references=predictions.label_ids)`,highlighted:`<span class="hljs-keyword">import</span> evaluate

metric = evaluate.load(<span class="hljs-string">&quot;glue&quot;</span>, <span class="hljs-string">&quot;mrpc&quot;</span>)
metric.compute(predictions=preds, references=predictions.label_ids)`}}),xe=new F({props:{code:"{'accuracy': 0.8578431372549019, 'f1': 0.8996539792387542}",highlighted:'{<span class="hljs-string">&#x27;accuracy&#x27;</span>: <span class="hljs-number">0.8578431372549019</span>, <span class="hljs-string">&#x27;f1&#x27;</span>: <span class="hljs-number">0.8996539792387542</span>}'}}),ze=new F({props:{code:`def compute_metrics(eval_preds):
    metric = evaluate.load("glue", "mrpc")
    logits, labels = eval_preds
    predictions = np.argmax(logits, axis=-1)
    return metric.compute(predictions=predictions, references=labels)`,highlighted:`<span class="hljs-keyword">def</span> <span class="hljs-title function_">compute_metrics</span>(<span class="hljs-params">eval_preds</span>):
    metric = evaluate.load(<span class="hljs-string">&quot;glue&quot;</span>, <span class="hljs-string">&quot;mrpc&quot;</span>)
    logits, labels = eval_preds
    predictions = np.argmax(logits, axis=-<span class="hljs-number">1</span>)
    <span class="hljs-keyword">return</span> metric.compute(predictions=predictions, references=labels)`}}),Se=new F({props:{code:`training_args = TrainingArguments("test-trainer", evaluation_strategy="epoch")
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)

trainer = Trainer(
    model,
    training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    data_collator=data_collator,
    tokenizer=tokenizer,
    compute_metrics=compute_metrics,
)`,highlighted:`training_args = TrainingArguments(<span class="hljs-string">&quot;test-trainer&quot;</span>, evaluation_strategy=<span class="hljs-string">&quot;epoch&quot;</span>)
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=<span class="hljs-number">2</span>)

trainer = Trainer(
    model,
    training_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,
    tokenizer=tokenizer,
    compute_metrics=compute_metrics,
)`}}),Fe=new F({props:{code:"trainer.train()",highlighted:"trainer.train()"}}),pe=new ln({props:{$$slots:{default:[_n]},$$scope:{ctx:ve}}}),{c(){p=s("meta"),A=c(),w(f.$$.fragment),x=c(),T=s("h1"),b=s("a"),k=s("span"),w(q.$$.fragment),B=c(),te=s("span"),ae=o("Fine-tuning a model with the Trainer API"),z=c(),w(Y.$$.fragment),_e=c(),w(J.$$.fragment),sa=c(),S=s("p"),Xa=o("\u{1F917} Transformers provides a "),Qe=s("code"),Ka=o("Trainer"),Qa=o(" class to help you fine-tune any of the pretrained models it provides on your dataset. Once you\u2019ve done all the data preprocessing work in the last section, you have just a few steps left to define the "),Ve=s("code"),Va=o("Trainer"),Za=o(". The hardest part is likely to be preparing the environment to run "),Ze=s("code"),eo=o("Trainer.train()"),to=o(", as it will run very slowly on a CPU. If you don\u2019t have a GPU set up, you can get access to free GPUs or TPUs on "),ge=s("a"),ao=o("Google Colab"),oo=o("."),ia=c(),We=s("p"),ro=o("The code examples below assume you have already executed the examples in the previous section. Here is a short summary recapping what you need:"),na=c(),w($e.$$.fragment),la=c(),oe=s("h3"),ie=s("a"),et=s("span"),w(Ee.$$.fragment),so=c(),tt=s("span"),io=o("Training"),da=c(),I=s("p"),no=o("The first step before we can define our "),at=s("code"),lo=o("Trainer"),co=o(" is to define a "),ot=s("code"),ho=o("TrainingArguments"),po=o(" class that will contain all the hyperparameters the "),rt=s("code"),uo=o("Trainer"),fo=o(" will use for training and evaluation. The only argument you have to provide is a directory where the trained model will be saved, as well as the checkpoints along the way. For all the rest, you can leave the defaults, which should work pretty well for a basic fine-tuning."),ca=c(),w(be.$$.fragment),ha=c(),w(ne.$$.fragment),pa=c(),X=s("p"),mo=o("The second step is to define our model. As in the "),Ue=s("a"),wo=o("previous chapter"),vo=o(", we will use the "),st=s("code"),_o=o("AutoModelForSequenceClassification"),go=o(" class, with two labels:"),ua=c(),w(ye.$$.fragment),fa=c(),le=s("p"),$o=o("You will notice that unlike in "),Ge=s("a"),Eo=o("Chapter 2"),bo=o(", you get a warning after instantiating this pretrained model. This is because BERT has not been pretrained on classifying pairs of sentences, so the head of the pretrained model has been discarded and a new head suitable for sequence classification has been added instead. The warnings indicate that some weights were not used (the ones corresponding to the dropped pretraining head) and that some others were randomly initialized (the ones for the new head). It concludes by encouraging you to train the model, which is exactly what we are going to do now."),ma=c(),C=s("p"),yo=o("Once we have our model, we can define a "),it=s("code"),To=o("Trainer"),ko=o(" by passing it all the objects constructed up to now \u2014 the "),nt=s("code"),Co=o("model"),jo=o(", the "),lt=s("code"),Oo=o("training_args"),Po=o(", the training and validation datasets, our "),dt=s("code"),Do=o("data_collator"),Ao=o(", and our "),ct=s("code"),xo=o("tokenizer"),qo=o(":"),wa=c(),w(Te.$$.fragment),va=c(),j=s("p"),zo=o("Note that when you pass the "),ht=s("code"),So=o("tokenizer"),Fo=o(" as we did here, the default "),pt=s("code"),Io=o("data_collator"),Wo=o(" used by the "),ut=s("code"),Uo=o("Trainer"),Go=o(" will be a "),ft=s("code"),Mo=o("DataCollatorWithPadding"),No=o(" as defined previously, so you can skip the line "),mt=s("code"),Lo=o("data_collator=data_collator"),Ro=o(" in this call. It was still important to show you this part of the processing in section 2!"),_a=c(),K=s("p"),Ho=o("To fine-tune the model on our dataset, we just have to call the "),wt=s("code"),Bo=o("train()"),Yo=o(" method of our "),vt=s("code"),Jo=o("Trainer"),Xo=o(":"),ga=c(),w(ke.$$.fragment),$a=c(),Me=s("p"),Ko=o("This will start the fine-tuning (which should take a couple of minutes on a GPU) and report the training loss every 500 steps. It won\u2019t, however, tell you how well (or badly) your model is performing. This is because:"),Ea=c(),de=s("ol"),D=s("li"),Qo=o("We didn\u2019t tell the "),_t=s("code"),Vo=o("Trainer"),Zo=o(" to evaluate during training by setting "),gt=s("code"),er=o("evaluation_strategy"),tr=o(" to either "),$t=s("code"),ar=o('"steps"'),or=o(" (evaluate every "),Et=s("code"),rr=o("eval_steps"),sr=o(") or "),bt=s("code"),ir=o('"epoch"'),nr=o(" (evaluate at the end of each epoch)."),lr=c(),re=s("li"),dr=o("We didn\u2019t provide the "),yt=s("code"),cr=o("Trainer"),hr=o(" with a "),Tt=s("code"),pr=o("compute_metrics()"),ur=o(" function to calculate a metric during said evaluation (otherwise the evaluation would just have printed the loss, which is not a very intuitive number)."),ba=c(),se=s("h3"),ce=s("a"),kt=s("span"),w(Ce.$$.fragment),fr=c(),Ct=s("span"),mr=o("Evaluation"),ya=c(),O=s("p"),wr=o("Let\u2019s see how we can build a useful "),jt=s("code"),vr=o("compute_metrics()"),_r=o(" function and use it the next time we train. The function must take an "),Ot=s("code"),gr=o("EvalPrediction"),$r=o(" object (which is a named tuple with a "),Pt=s("code"),Er=o("predictions"),br=o(" field and a "),Dt=s("code"),yr=o("label_ids"),Tr=o(" field) and will return a dictionary mapping strings to floats (the strings being the names of the metrics returned, and the floats their values). To get some predictions from our model, we can use the "),At=s("code"),kr=o("Trainer.predict()"),Cr=o(" command:"),Ta=c(),w(je.$$.fragment),ka=c(),w(Oe.$$.fragment),Ca=c(),m=s("p"),jr=o("The output of the "),xt=s("code"),Or=o("predict()"),Pr=o(" method is another named tuple with three fields: "),qt=s("code"),Dr=o("predictions"),Ar=o(", "),zt=s("code"),xr=o("label_ids"),qr=o(", and "),St=s("code"),zr=o("metrics"),Sr=o(". The "),Ft=s("code"),Fr=o("metrics"),Ir=o(" field will just contain the loss on the dataset passed, as well as some time metrics (how long it took to predict, in total and on average). Once we complete our "),It=s("code"),Wr=o("compute_metrics()"),Ur=o(" function and pass it to the "),Wt=s("code"),Gr=o("Trainer"),Mr=o(", that field will also contain the metrics returned by "),Ut=s("code"),Nr=o("compute_metrics()"),Lr=o("."),ja=c(),W=s("p"),Rr=o("As you can see, "),Gt=s("code"),Hr=o("predictions"),Br=o(" is a two-dimensional array with shape 408 x 2 (408 being the number of elements in the dataset we used). Those are the logits for each element of the dataset we passed to "),Mt=s("code"),Yr=o("predict()"),Jr=o(" (as you saw in the "),Ne=s("a"),Xr=o("previous chapter"),Kr=o(", all Transformer models return logits). To transform them into predictions that we can compare to our labels, we need to take the index with the maximum value on the second axis:"),Oa=c(),w(Pe.$$.fragment),Pa=c(),P=s("p"),Qr=o("We can now compare those "),Nt=s("code"),Vr=o("preds"),Zr=o(" to the labels. To build our "),Lt=s("code"),es=o("compute_metric()"),ts=o(" function, we will rely on the metrics from the \u{1F917} "),De=s("a"),as=o("Evaluate"),os=o(" library. We can load the metrics associated with the MRPC dataset as easily as we loaded the dataset, this time with the "),Rt=s("code"),rs=o("evaluate.load()"),ss=o(" function. The object returned has a "),Ht=s("code"),is=o("compute()"),ns=o(" method we can use to do the metric calculation:"),Da=c(),w(Ae.$$.fragment),Aa=c(),w(xe.$$.fragment),xa=c(),U=s("p"),ls=o("The exact results you get may vary, as the random initialization of the model head might change the metrics it achieved. Here, we can see our model has an accuracy of 85.78% on the validation set and an F1 score of 89.97. Those are the two metrics used to evaluate results on the MRPC dataset for the GLUE benchmark. The table in the "),qe=s("a"),ds=o("BERT paper"),cs=o(" reported an F1 score of 88.9 for the base model. That was the "),Bt=s("code"),hs=o("uncased"),ps=o(" model while we are currently using the "),Yt=s("code"),us=o("cased"),fs=o(" model, which explains the better result."),qa=c(),he=s("p"),ms=o("Wrapping everything together, we get our "),Jt=s("code"),ws=o("compute_metrics()"),vs=o(" function:"),za=c(),w(ze.$$.fragment),Sa=c(),Q=s("p"),_s=o("And to see it used in action to report metrics at the end of each epoch, here is how we define a new "),Xt=s("code"),gs=o("Trainer"),$s=o(" with this "),Kt=s("code"),Es=o("compute_metrics()"),bs=o(" function:"),Fa=c(),w(Se.$$.fragment),Ia=c(),G=s("p"),ys=o("Note that we create a new "),Qt=s("code"),Ts=o("TrainingArguments"),ks=o(" with its "),Vt=s("code"),Cs=o("evaluation_strategy"),js=o(" set to "),Zt=s("code"),Os=o('"epoch"'),Ps=o(" and a new model \u2014 otherwise, we would just be continuing the training of the model we have already trained. To launch a new training run, we execute:"),Wa=c(),w(Fe.$$.fragment),Ua=c(),Le=s("p"),Ds=o("This time, it will report the validation loss and metrics at the end of each epoch on top of the training loss. Again, the exact accuracy/F1 score you reach might be a bit different from what we found, because of the random head initialization of the model, but it should be in the same ballpark."),Ga=c(),V=s("p"),As=o("The "),ea=s("code"),xs=o("Trainer"),qs=o(" will work out of the box on multiple GPUs or TPUs and provides lots of options, like mixed-precision training (use "),ta=s("code"),zs=o("fp16 = True"),Ss=o(" in your training arguments). We will go over everything it supports in Chapter 10."),Ma=c(),Z=s("p"),Fs=o("This concludes the introduction to fine-tuning using the "),aa=s("code"),Is=o("Trainer"),Ws=o(" API. An example of doing this for most common NLP tasks will be given in "),Re=s("a"),Us=o("Chapter 7"),Gs=o(", but for now let\u2019s look at how to do the same thing in pure PyTorch."),Na=c(),w(pe.$$.fragment),this.h()},l(e){const l=pn('[data-svelte="svelte-1phssyn"]',document.head);p=i(l,"META",{name:!0,content:!0}),l.forEach(a),A=h(e),v(f.$$.fragment,e),x=h(e),T=i(e,"H1",{class:!0});var Ie=n(T);b=i(Ie,"A",{id:!0,class:!0,href:!0});var oa=n(b);k=i(oa,"SPAN",{});var ra=n(k);v(q.$$.fragment,ra),ra.forEach(a),oa.forEach(a),B=h(Ie),te=i(Ie,"SPAN",{});var Ns=n(te);ae=r(Ns,"Fine-tuning a model with the Trainer API"),Ns.forEach(a),Ie.forEach(a),z=h(e),v(Y.$$.fragment,e),_e=h(e),v(J.$$.fragment,e),sa=h(e),S=i(e,"P",{});var ee=n(S);Xa=r(ee,"\u{1F917} Transformers provides a "),Qe=i(ee,"CODE",{});var Ls=n(Qe);Ka=r(Ls,"Trainer"),Ls.forEach(a),Qa=r(ee," class to help you fine-tune any of the pretrained models it provides on your dataset. Once you\u2019ve done all the data preprocessing work in the last section, you have just a few steps left to define the "),Ve=i(ee,"CODE",{});var Rs=n(Ve);Va=r(Rs,"Trainer"),Rs.forEach(a),Za=r(ee,". The hardest part is likely to be preparing the environment to run "),Ze=i(ee,"CODE",{});var Hs=n(Ze);eo=r(Hs,"Trainer.train()"),Hs.forEach(a),to=r(ee,", as it will run very slowly on a CPU. If you don\u2019t have a GPU set up, you can get access to free GPUs or TPUs on "),ge=i(ee,"A",{href:!0,rel:!0});var Bs=n(ge);ao=r(Bs,"Google Colab"),Bs.forEach(a),oo=r(ee,"."),ee.forEach(a),ia=h(e),We=i(e,"P",{});var Ys=n(We);ro=r(Ys,"The code examples below assume you have already executed the examples in the previous section. Here is a short summary recapping what you need:"),Ys.forEach(a),na=h(e),v($e.$$.fragment,e),la=h(e),oe=i(e,"H3",{class:!0});var Ra=n(oe);ie=i(Ra,"A",{id:!0,class:!0,href:!0});var Js=n(ie);et=i(Js,"SPAN",{});var Xs=n(et);v(Ee.$$.fragment,Xs),Xs.forEach(a),Js.forEach(a),so=h(Ra),tt=i(Ra,"SPAN",{});var Ks=n(tt);io=r(Ks,"Training"),Ks.forEach(a),Ra.forEach(a),da=h(e),I=i(e,"P",{});var ue=n(I);no=r(ue,"The first step before we can define our "),at=i(ue,"CODE",{});var Qs=n(at);lo=r(Qs,"Trainer"),Qs.forEach(a),co=r(ue," is to define a "),ot=i(ue,"CODE",{});var Vs=n(ot);ho=r(Vs,"TrainingArguments"),Vs.forEach(a),po=r(ue," class that will contain all the hyperparameters the "),rt=i(ue,"CODE",{});var Zs=n(rt);uo=r(Zs,"Trainer"),Zs.forEach(a),fo=r(ue," will use for training and evaluation. The only argument you have to provide is a directory where the trained model will be saved, as well as the checkpoints along the way. For all the rest, you can leave the defaults, which should work pretty well for a basic fine-tuning."),ue.forEach(a),ca=h(e),v(be.$$.fragment,e),ha=h(e),v(ne.$$.fragment,e),pa=h(e),X=i(e,"P",{});var He=n(X);mo=r(He,"The second step is to define our model. As in the "),Ue=i(He,"A",{href:!0});var ei=n(Ue);wo=r(ei,"previous chapter"),ei.forEach(a),vo=r(He,", we will use the "),st=i(He,"CODE",{});var ti=n(st);_o=r(ti,"AutoModelForSequenceClassification"),ti.forEach(a),go=r(He," class, with two labels:"),He.forEach(a),ua=h(e),v(ye.$$.fragment,e),fa=h(e),le=i(e,"P",{});var Ha=n(le);$o=r(Ha,"You will notice that unlike in "),Ge=i(Ha,"A",{href:!0});var ai=n(Ge);Eo=r(ai,"Chapter 2"),ai.forEach(a),bo=r(Ha,", you get a warning after instantiating this pretrained model. This is because BERT has not been pretrained on classifying pairs of sentences, so the head of the pretrained model has been discarded and a new head suitable for sequence classification has been added instead. The warnings indicate that some weights were not used (the ones corresponding to the dropped pretraining head) and that some others were randomly initialized (the ones for the new head). It concludes by encouraging you to train the model, which is exactly what we are going to do now."),Ha.forEach(a),ma=h(e),C=i(e,"P",{});var M=n(C);yo=r(M,"Once we have our model, we can define a "),it=i(M,"CODE",{});var oi=n(it);To=r(oi,"Trainer"),oi.forEach(a),ko=r(M," by passing it all the objects constructed up to now \u2014 the "),nt=i(M,"CODE",{});var ri=n(nt);Co=r(ri,"model"),ri.forEach(a),jo=r(M,", the "),lt=i(M,"CODE",{});var si=n(lt);Oo=r(si,"training_args"),si.forEach(a),Po=r(M,", the training and validation datasets, our "),dt=i(M,"CODE",{});var ii=n(dt);Do=r(ii,"data_collator"),ii.forEach(a),Ao=r(M,", and our "),ct=i(M,"CODE",{});var ni=n(ct);xo=r(ni,"tokenizer"),ni.forEach(a),qo=r(M,":"),M.forEach(a),wa=h(e),v(Te.$$.fragment,e),va=h(e),j=i(e,"P",{});var N=n(j);zo=r(N,"Note that when you pass the "),ht=i(N,"CODE",{});var li=n(ht);So=r(li,"tokenizer"),li.forEach(a),Fo=r(N," as we did here, the default "),pt=i(N,"CODE",{});var di=n(pt);Io=r(di,"data_collator"),di.forEach(a),Wo=r(N," used by the "),ut=i(N,"CODE",{});var ci=n(ut);Uo=r(ci,"Trainer"),ci.forEach(a),Go=r(N," will be a "),ft=i(N,"CODE",{});var hi=n(ft);Mo=r(hi,"DataCollatorWithPadding"),hi.forEach(a),No=r(N," as defined previously, so you can skip the line "),mt=i(N,"CODE",{});var pi=n(mt);Lo=r(pi,"data_collator=data_collator"),pi.forEach(a),Ro=r(N," in this call. It was still important to show you this part of the processing in section 2!"),N.forEach(a),_a=h(e),K=i(e,"P",{});var Be=n(K);Ho=r(Be,"To fine-tune the model on our dataset, we just have to call the "),wt=i(Be,"CODE",{});var ui=n(wt);Bo=r(ui,"train()"),ui.forEach(a),Yo=r(Be," method of our "),vt=i(Be,"CODE",{});var fi=n(vt);Jo=r(fi,"Trainer"),fi.forEach(a),Xo=r(Be,":"),Be.forEach(a),ga=h(e),v(ke.$$.fragment,e),$a=h(e),Me=i(e,"P",{});var mi=n(Me);Ko=r(mi,"This will start the fine-tuning (which should take a couple of minutes on a GPU) and report the training loss every 500 steps. It won\u2019t, however, tell you how well (or badly) your model is performing. This is because:"),mi.forEach(a),Ea=h(e),de=i(e,"OL",{});var Ba=n(de);D=i(Ba,"LI",{});var L=n(D);Qo=r(L,"We didn\u2019t tell the "),_t=i(L,"CODE",{});var wi=n(_t);Vo=r(wi,"Trainer"),wi.forEach(a),Zo=r(L," to evaluate during training by setting "),gt=i(L,"CODE",{});var vi=n(gt);er=r(vi,"evaluation_strategy"),vi.forEach(a),tr=r(L," to either "),$t=i(L,"CODE",{});var _i=n($t);ar=r(_i,'"steps"'),_i.forEach(a),or=r(L," (evaluate every "),Et=i(L,"CODE",{});var gi=n(Et);rr=r(gi,"eval_steps"),gi.forEach(a),sr=r(L,") or "),bt=i(L,"CODE",{});var $i=n(bt);ir=r($i,'"epoch"'),$i.forEach(a),nr=r(L," (evaluate at the end of each epoch)."),L.forEach(a),lr=h(Ba),re=i(Ba,"LI",{});var Ye=n(re);dr=r(Ye,"We didn\u2019t provide the "),yt=i(Ye,"CODE",{});var Ei=n(yt);cr=r(Ei,"Trainer"),Ei.forEach(a),hr=r(Ye," with a "),Tt=i(Ye,"CODE",{});var bi=n(Tt);pr=r(bi,"compute_metrics()"),bi.forEach(a),ur=r(Ye," function to calculate a metric during said evaluation (otherwise the evaluation would just have printed the loss, which is not a very intuitive number)."),Ye.forEach(a),Ba.forEach(a),ba=h(e),se=i(e,"H3",{class:!0});var Ya=n(se);ce=i(Ya,"A",{id:!0,class:!0,href:!0});var yi=n(ce);kt=i(yi,"SPAN",{});var Ti=n(kt);v(Ce.$$.fragment,Ti),Ti.forEach(a),yi.forEach(a),fr=h(Ya),Ct=i(Ya,"SPAN",{});var ki=n(Ct);mr=r(ki,"Evaluation"),ki.forEach(a),Ya.forEach(a),ya=h(e),O=i(e,"P",{});var R=n(O);wr=r(R,"Let\u2019s see how we can build a useful "),jt=i(R,"CODE",{});var Ci=n(jt);vr=r(Ci,"compute_metrics()"),Ci.forEach(a),_r=r(R," function and use it the next time we train. The function must take an "),Ot=i(R,"CODE",{});var ji=n(Ot);gr=r(ji,"EvalPrediction"),ji.forEach(a),$r=r(R," object (which is a named tuple with a "),Pt=i(R,"CODE",{});var Oi=n(Pt);Er=r(Oi,"predictions"),Oi.forEach(a),br=r(R," field and a "),Dt=i(R,"CODE",{});var Pi=n(Dt);yr=r(Pi,"label_ids"),Pi.forEach(a),Tr=r(R," field) and will return a dictionary mapping strings to floats (the strings being the names of the metrics returned, and the floats their values). To get some predictions from our model, we can use the "),At=i(R,"CODE",{});var Di=n(At);kr=r(Di,"Trainer.predict()"),Di.forEach(a),Cr=r(R," command:"),R.forEach(a),Ta=h(e),v(je.$$.fragment,e),ka=h(e),v(Oe.$$.fragment,e),Ca=h(e),m=i(e,"P",{});var y=n(m);jr=r(y,"The output of the "),xt=i(y,"CODE",{});var Ai=n(xt);Or=r(Ai,"predict()"),Ai.forEach(a),Pr=r(y," method is another named tuple with three fields: "),qt=i(y,"CODE",{});var xi=n(qt);Dr=r(xi,"predictions"),xi.forEach(a),Ar=r(y,", "),zt=i(y,"CODE",{});var qi=n(zt);xr=r(qi,"label_ids"),qi.forEach(a),qr=r(y,", and "),St=i(y,"CODE",{});var zi=n(St);zr=r(zi,"metrics"),zi.forEach(a),Sr=r(y,". The "),Ft=i(y,"CODE",{});var Si=n(Ft);Fr=r(Si,"metrics"),Si.forEach(a),Ir=r(y," field will just contain the loss on the dataset passed, as well as some time metrics (how long it took to predict, in total and on average). Once we complete our "),It=i(y,"CODE",{});var Fi=n(It);Wr=r(Fi,"compute_metrics()"),Fi.forEach(a),Ur=r(y," function and pass it to the "),Wt=i(y,"CODE",{});var Ii=n(Wt);Gr=r(Ii,"Trainer"),Ii.forEach(a),Mr=r(y,", that field will also contain the metrics returned by "),Ut=i(y,"CODE",{});var Wi=n(Ut);Nr=r(Wi,"compute_metrics()"),Wi.forEach(a),Lr=r(y,"."),y.forEach(a),ja=h(e),W=i(e,"P",{});var fe=n(W);Rr=r(fe,"As you can see, "),Gt=i(fe,"CODE",{});var Ui=n(Gt);Hr=r(Ui,"predictions"),Ui.forEach(a),Br=r(fe," is a two-dimensional array with shape 408 x 2 (408 being the number of elements in the dataset we used). Those are the logits for each element of the dataset we passed to "),Mt=i(fe,"CODE",{});var Gi=n(Mt);Yr=r(Gi,"predict()"),Gi.forEach(a),Jr=r(fe," (as you saw in the "),Ne=i(fe,"A",{href:!0});var Mi=n(Ne);Xr=r(Mi,"previous chapter"),Mi.forEach(a),Kr=r(fe,", all Transformer models return logits). To transform them into predictions that we can compare to our labels, we need to take the index with the maximum value on the second axis:"),fe.forEach(a),Oa=h(e),v(Pe.$$.fragment,e),Pa=h(e),P=i(e,"P",{});var H=n(P);Qr=r(H,"We can now compare those "),Nt=i(H,"CODE",{});var Ni=n(Nt);Vr=r(Ni,"preds"),Ni.forEach(a),Zr=r(H," to the labels. To build our "),Lt=i(H,"CODE",{});var Li=n(Lt);es=r(Li,"compute_metric()"),Li.forEach(a),ts=r(H," function, we will rely on the metrics from the \u{1F917} "),De=i(H,"A",{href:!0,rel:!0});var Ri=n(De);as=r(Ri,"Evaluate"),Ri.forEach(a),os=r(H," library. We can load the metrics associated with the MRPC dataset as easily as we loaded the dataset, this time with the "),Rt=i(H,"CODE",{});var Hi=n(Rt);rs=r(Hi,"evaluate.load()"),Hi.forEach(a),ss=r(H," function. The object returned has a "),Ht=i(H,"CODE",{});var Bi=n(Ht);is=r(Bi,"compute()"),Bi.forEach(a),ns=r(H," method we can use to do the metric calculation:"),H.forEach(a),Da=h(e),v(Ae.$$.fragment,e),Aa=h(e),v(xe.$$.fragment,e),xa=h(e),U=i(e,"P",{});var me=n(U);ls=r(me,"The exact results you get may vary, as the random initialization of the model head might change the metrics it achieved. Here, we can see our model has an accuracy of 85.78% on the validation set and an F1 score of 89.97. Those are the two metrics used to evaluate results on the MRPC dataset for the GLUE benchmark. The table in the "),qe=i(me,"A",{href:!0,rel:!0});var Yi=n(qe);ds=r(Yi,"BERT paper"),Yi.forEach(a),cs=r(me," reported an F1 score of 88.9 for the base model. That was the "),Bt=i(me,"CODE",{});var Ji=n(Bt);hs=r(Ji,"uncased"),Ji.forEach(a),ps=r(me," model while we are currently using the "),Yt=i(me,"CODE",{});var Xi=n(Yt);us=r(Xi,"cased"),Xi.forEach(a),fs=r(me," model, which explains the better result."),me.forEach(a),qa=h(e),he=i(e,"P",{});var Ja=n(he);ms=r(Ja,"Wrapping everything together, we get our "),Jt=i(Ja,"CODE",{});var Ki=n(Jt);ws=r(Ki,"compute_metrics()"),Ki.forEach(a),vs=r(Ja," function:"),Ja.forEach(a),za=h(e),v(ze.$$.fragment,e),Sa=h(e),Q=i(e,"P",{});var Je=n(Q);_s=r(Je,"And to see it used in action to report metrics at the end of each epoch, here is how we define a new "),Xt=i(Je,"CODE",{});var Qi=n(Xt);gs=r(Qi,"Trainer"),Qi.forEach(a),$s=r(Je," with this "),Kt=i(Je,"CODE",{});var Vi=n(Kt);Es=r(Vi,"compute_metrics()"),Vi.forEach(a),bs=r(Je," function:"),Je.forEach(a),Fa=h(e),v(Se.$$.fragment,e),Ia=h(e),G=i(e,"P",{});var we=n(G);ys=r(we,"Note that we create a new "),Qt=i(we,"CODE",{});var Zi=n(Qt);Ts=r(Zi,"TrainingArguments"),Zi.forEach(a),ks=r(we," with its "),Vt=i(we,"CODE",{});var en=n(Vt);Cs=r(en,"evaluation_strategy"),en.forEach(a),js=r(we," set to "),Zt=i(we,"CODE",{});var tn=n(Zt);Os=r(tn,'"epoch"'),tn.forEach(a),Ps=r(we," and a new model \u2014 otherwise, we would just be continuing the training of the model we have already trained. To launch a new training run, we execute:"),we.forEach(a),Wa=h(e),v(Fe.$$.fragment,e),Ua=h(e),Le=i(e,"P",{});var an=n(Le);Ds=r(an,"This time, it will report the validation loss and metrics at the end of each epoch on top of the training loss. Again, the exact accuracy/F1 score you reach might be a bit different from what we found, because of the random head initialization of the model, but it should be in the same ballpark."),an.forEach(a),Ga=h(e),V=i(e,"P",{});var Xe=n(V);As=r(Xe,"The "),ea=i(Xe,"CODE",{});var on=n(ea);xs=r(on,"Trainer"),on.forEach(a),qs=r(Xe," will work out of the box on multiple GPUs or TPUs and provides lots of options, like mixed-precision training (use "),ta=i(Xe,"CODE",{});var rn=n(ta);zs=r(rn,"fp16 = True"),rn.forEach(a),Ss=r(Xe," in your training arguments). We will go over everything it supports in Chapter 10."),Xe.forEach(a),Ma=h(e),Z=i(e,"P",{});var Ke=n(Z);Fs=r(Ke,"This concludes the introduction to fine-tuning using the "),aa=i(Ke,"CODE",{});var sn=n(aa);Is=r(sn,"Trainer"),sn.forEach(a),Ws=r(Ke," API. An example of doing this for most common NLP tasks will be given in "),Re=i(Ke,"A",{href:!0});var nn=n(Re);Us=r(nn,"Chapter 7"),nn.forEach(a),Gs=r(Ke,", but for now let\u2019s look at how to do the same thing in pure PyTorch."),Ke.forEach(a),Na=h(e),v(pe.$$.fragment,e),this.h()},h(){u(p,"name","hf:doc:metadata"),u(p,"content",JSON.stringify($n)),u(b,"id","fine-tuning-a-model-with-the-trainer-api"),u(b,"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"),u(b,"href","#fine-tuning-a-model-with-the-trainer-api"),u(T,"class","relative group"),u(ge,"href","https://colab.research.google.com/"),u(ge,"rel","nofollow"),u(ie,"id","training"),u(ie,"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"),u(ie,"href","#training"),u(oe,"class","relative group"),u(Ue,"href","/course/chapter2"),u(Ge,"href","/course/chapter2"),u(ce,"id","evaluation"),u(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"),u(ce,"href","#evaluation"),u(se,"class","relative group"),u(Ne,"href","/course/chapter2"),u(De,"href","https://github.com/huggingface/evaluate/"),u(De,"rel","nofollow"),u(qe,"href","https://arxiv.org/pdf/1810.04805.pdf"),u(qe,"rel","nofollow"),u(Re,"href","/course/chapter7")},m(e,l){t(document.head,p),d(e,A,l),_(f,e,l),d(e,x,l),d(e,T,l),t(T,b),t(b,k),_(q,k,null),t(T,B),t(T,te),t(te,ae),d(e,z,l),_(Y,e,l),d(e,_e,l),_(J,e,l),d(e,sa,l),d(e,S,l),t(S,Xa),t(S,Qe),t(Qe,Ka),t(S,Qa),t(S,Ve),t(Ve,Va),t(S,Za),t(S,Ze),t(Ze,eo),t(S,to),t(S,ge),t(ge,ao),t(S,oo),d(e,ia,l),d(e,We,l),t(We,ro),d(e,na,l),_($e,e,l),d(e,la,l),d(e,oe,l),t(oe,ie),t(ie,et),_(Ee,et,null),t(oe,so),t(oe,tt),t(tt,io),d(e,da,l),d(e,I,l),t(I,no),t(I,at),t(at,lo),t(I,co),t(I,ot),t(ot,ho),t(I,po),t(I,rt),t(rt,uo),t(I,fo),d(e,ca,l),_(be,e,l),d(e,ha,l),_(ne,e,l),d(e,pa,l),d(e,X,l),t(X,mo),t(X,Ue),t(Ue,wo),t(X,vo),t(X,st),t(st,_o),t(X,go),d(e,ua,l),_(ye,e,l),d(e,fa,l),d(e,le,l),t(le,$o),t(le,Ge),t(Ge,Eo),t(le,bo),d(e,ma,l),d(e,C,l),t(C,yo),t(C,it),t(it,To),t(C,ko),t(C,nt),t(nt,Co),t(C,jo),t(C,lt),t(lt,Oo),t(C,Po),t(C,dt),t(dt,Do),t(C,Ao),t(C,ct),t(ct,xo),t(C,qo),d(e,wa,l),_(Te,e,l),d(e,va,l),d(e,j,l),t(j,zo),t(j,ht),t(ht,So),t(j,Fo),t(j,pt),t(pt,Io),t(j,Wo),t(j,ut),t(ut,Uo),t(j,Go),t(j,ft),t(ft,Mo),t(j,No),t(j,mt),t(mt,Lo),t(j,Ro),d(e,_a,l),d(e,K,l),t(K,Ho),t(K,wt),t(wt,Bo),t(K,Yo),t(K,vt),t(vt,Jo),t(K,Xo),d(e,ga,l),_(ke,e,l),d(e,$a,l),d(e,Me,l),t(Me,Ko),d(e,Ea,l),d(e,de,l),t(de,D),t(D,Qo),t(D,_t),t(_t,Vo),t(D,Zo),t(D,gt),t(gt,er),t(D,tr),t(D,$t),t($t,ar),t(D,or),t(D,Et),t(Et,rr),t(D,sr),t(D,bt),t(bt,ir),t(D,nr),t(de,lr),t(de,re),t(re,dr),t(re,yt),t(yt,cr),t(re,hr),t(re,Tt),t(Tt,pr),t(re,ur),d(e,ba,l),d(e,se,l),t(se,ce),t(ce,kt),_(Ce,kt,null),t(se,fr),t(se,Ct),t(Ct,mr),d(e,ya,l),d(e,O,l),t(O,wr),t(O,jt),t(jt,vr),t(O,_r),t(O,Ot),t(Ot,gr),t(O,$r),t(O,Pt),t(Pt,Er),t(O,br),t(O,Dt),t(Dt,yr),t(O,Tr),t(O,At),t(At,kr),t(O,Cr),d(e,Ta,l),_(je,e,l),d(e,ka,l),_(Oe,e,l),d(e,Ca,l),d(e,m,l),t(m,jr),t(m,xt),t(xt,Or),t(m,Pr),t(m,qt),t(qt,Dr),t(m,Ar),t(m,zt),t(zt,xr),t(m,qr),t(m,St),t(St,zr),t(m,Sr),t(m,Ft),t(Ft,Fr),t(m,Ir),t(m,It),t(It,Wr),t(m,Ur),t(m,Wt),t(Wt,Gr),t(m,Mr),t(m,Ut),t(Ut,Nr),t(m,Lr),d(e,ja,l),d(e,W,l),t(W,Rr),t(W,Gt),t(Gt,Hr),t(W,Br),t(W,Mt),t(Mt,Yr),t(W,Jr),t(W,Ne),t(Ne,Xr),t(W,Kr),d(e,Oa,l),_(Pe,e,l),d(e,Pa,l),d(e,P,l),t(P,Qr),t(P,Nt),t(Nt,Vr),t(P,Zr),t(P,Lt),t(Lt,es),t(P,ts),t(P,De),t(De,as),t(P,os),t(P,Rt),t(Rt,rs),t(P,ss),t(P,Ht),t(Ht,is),t(P,ns),d(e,Da,l),_(Ae,e,l),d(e,Aa,l),_(xe,e,l),d(e,xa,l),d(e,U,l),t(U,ls),t(U,qe),t(qe,ds),t(U,cs),t(U,Bt),t(Bt,hs),t(U,ps),t(U,Yt),t(Yt,us),t(U,fs),d(e,qa,l),d(e,he,l),t(he,ms),t(he,Jt),t(Jt,ws),t(he,vs),d(e,za,l),_(ze,e,l),d(e,Sa,l),d(e,Q,l),t(Q,_s),t(Q,Xt),t(Xt,gs),t(Q,$s),t(Q,Kt),t(Kt,Es),t(Q,bs),d(e,Fa,l),_(Se,e,l),d(e,Ia,l),d(e,G,l),t(G,ys),t(G,Qt),t(Qt,Ts),t(G,ks),t(G,Vt),t(Vt,Cs),t(G,js),t(G,Zt),t(Zt,Os),t(G,Ps),d(e,Wa,l),_(Fe,e,l),d(e,Ua,l),d(e,Le,l),t(Le,Ds),d(e,Ga,l),d(e,V,l),t(V,As),t(V,ea),t(ea,xs),t(V,qs),t(V,ta),t(ta,zs),t(V,Ss),d(e,Ma,l),d(e,Z,l),t(Z,Fs),t(Z,aa),t(aa,Is),t(Z,Ws),t(Z,Re),t(Re,Us),t(Z,Gs),d(e,Na,l),_(pe,e,l),La=!0},p(e,[l]){const Ie={};l&1&&(Ie.fw=e[0]),f.$set(Ie);const oa={};l&2&&(oa.$$scope={dirty:l,ctx:e}),ne.$set(oa);const ra={};l&2&&(ra.$$scope={dirty:l,ctx:e}),pe.$set(ra)},i(e){La||(g(f.$$.fragment,e),g(q.$$.fragment,e),g(Y.$$.fragment,e),g(J.$$.fragment,e),g($e.$$.fragment,e),g(Ee.$$.fragment,e),g(be.$$.fragment,e),g(ne.$$.fragment,e),g(ye.$$.fragment,e),g(Te.$$.fragment,e),g(ke.$$.fragment,e),g(Ce.$$.fragment,e),g(je.$$.fragment,e),g(Oe.$$.fragment,e),g(Pe.$$.fragment,e),g(Ae.$$.fragment,e),g(xe.$$.fragment,e),g(ze.$$.fragment,e),g(Se.$$.fragment,e),g(Fe.$$.fragment,e),g(pe.$$.fragment,e),La=!0)},o(e){$(f.$$.fragment,e),$(q.$$.fragment,e),$(Y.$$.fragment,e),$(J.$$.fragment,e),$($e.$$.fragment,e),$(Ee.$$.fragment,e),$(be.$$.fragment,e),$(ne.$$.fragment,e),$(ye.$$.fragment,e),$(Te.$$.fragment,e),$(ke.$$.fragment,e),$(Ce.$$.fragment,e),$(je.$$.fragment,e),$(Oe.$$.fragment,e),$(Pe.$$.fragment,e),$(Ae.$$.fragment,e),$(xe.$$.fragment,e),$(ze.$$.fragment,e),$(Se.$$.fragment,e),$(Fe.$$.fragment,e),$(pe.$$.fragment,e),La=!1},d(e){a(p),e&&a(A),E(f,e),e&&a(x),e&&a(T),E(q),e&&a(z),E(Y,e),e&&a(_e),E(J,e),e&&a(sa),e&&a(S),e&&a(ia),e&&a(We),e&&a(na),E($e,e),e&&a(la),e&&a(oe),E(Ee),e&&a(da),e&&a(I),e&&a(ca),E(be,e),e&&a(ha),E(ne,e),e&&a(pa),e&&a(X),e&&a(ua),E(ye,e),e&&a(fa),e&&a(le),e&&a(ma),e&&a(C),e&&a(wa),E(Te,e),e&&a(va),e&&a(j),e&&a(_a),e&&a(K),e&&a(ga),E(ke,e),e&&a($a),e&&a(Me),e&&a(Ea),e&&a(de),e&&a(ba),e&&a(se),E(Ce),e&&a(ya),e&&a(O),e&&a(Ta),E(je,e),e&&a(ka),E(Oe,e),e&&a(Ca),e&&a(m),e&&a(ja),e&&a(W),e&&a(Oa),E(Pe,e),e&&a(Pa),e&&a(P),e&&a(Da),E(Ae,e),e&&a(Aa),E(xe,e),e&&a(xa),e&&a(U),e&&a(qa),e&&a(he),e&&a(za),E(ze,e),e&&a(Sa),e&&a(Q),e&&a(Fa),E(Se,e),e&&a(Ia),e&&a(G),e&&a(Wa),E(Fe,e),e&&a(Ua),e&&a(Le),e&&a(Ga),e&&a(V),e&&a(Ma),e&&a(Z),e&&a(Na),E(pe,e)}}}const $n={local:"fine-tuning-a-model-with-the-trainer-api",sections:[{local:"training",title:"Training"},{local:"evaluation",title:"Evaluation"}],title:"Fine-tuning a model with the Trainer API"};function En(ve,p,A){let f="pt";return un(()=>{const x=new URLSearchParams(window.location.search);A(0,f=x.get("fw")||"pt")}),[f]}class Pn extends dn{constructor(p){super();cn(this,p,En,gn,hn,{})}}export{Pn as default,$n as metadata};
