import{S as sl,i as tl,s as al,e as l,k as d,w as le,t as a,M as ol,c as r,d as t,m as c,a as n,x as re,h as o,b as f,G as e,g as i,y as ne,L as ll,q as pe,o as ie,B as de,v as rl}from"../chunks/vendor-hf-doc-builder.js";import{I as Ka}from"../chunks/IconCopyLink-hf-doc-builder.js";import{C as Qa}from"../chunks/CodeBlock-hf-doc-builder.js";function nl(Va){let C,fs,D,A,ce,R,Js,he,Rs,ms,E,Bs,ue,Fs,Ks,fe,Qs,Vs,_s,m,Ws,me,Zs,et,_e,st,tt,we,at,ot,ws,h,lt,ye,rt,nt,ke,pt,it,ve,dt,ct,ge,ht,ut,Ee,ft,mt,ys,B,ks,ee,_t,vs,T,be,wt,yt,je,kt,vt,gs,v,qe,gt,Et,Ce,bt,jt,De,qt,Ct,Es,P,Te,Dt,Tt,Pe,Pt,Ot,bs,g,Oe,$t,At,$e,St,xt,Ae,It,zt,js,u,Nt,Se,Lt,Ut,xe,Ht,Mt,Ie,Yt,Xt,ze,Gt,Jt,qs,S,Rt,Ne,Bt,Ft,Cs,F,Ds,_,Kt,Le,Qt,Vt,Ue,Wt,Zt,He,ea,sa,Ts,K,Ps,se,ta,Os,O,x,Me,Q,aa,Ye,oa,$s,b,la,Xe,ra,na,Ge,pa,ia,As,$,I,Je,V,da,Re,ca,Ss,z,ha,Be,ua,fa,xs,w,ma,Fe,_a,wa,Ke,ya,ka,Qe,va,ga,Is,j,Ea,Ve,ba,ja,We,qa,Ca,zs,N,Da,Ze,Ta,Pa,Ns,y,L,es,Oa,$a,ss,Aa,Sa,xa,U,ts,Ia,za,as,Na,La,Ua,H,os,Ha,Ma,ls,Ya,Xa,Ga,M,rs,Ja,Ra,ns,Ba,Fa,Ls;return R=new Ka({}),B=new Qa({props:{code:`from transformers import Pipeline


class MyPipeline(Pipeline):
    def _sanitize_parameters(self, **kwargs):
        preprocess_kwargs = {}
        if "maybe_arg" in kwargs:
            preprocess_kwargs["maybe_arg"] = kwargs["maybe_arg"]
        return preprocess_kwargs, {}, {}

    def preprocess(self, inputs, maybe_arg=2):
        model_input = Tensor(inputs["input_ids"])
        return {"model_input": model_input}

    def _forward(self, model_inputs):
        # model_inputs == {"model_input": model_input}
        outputs = self.model(**model_inputs)
        # Maybe {"logits": Tensor(...)}
        return outputs

    def postprocess(self, model_outputs):
        best_class = model_outputs["logits"].softmax(-1)
        return best_class`,highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> Pipeline


<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyPipeline</span>(<span class="hljs-title class_ inherited__">Pipeline</span>):
    <span class="hljs-keyword">def</span> <span class="hljs-title function_">_sanitize_parameters</span>(<span class="hljs-params">self, **kwargs</span>):
        preprocess_kwargs = {}
        <span class="hljs-keyword">if</span> <span class="hljs-string">&quot;maybe_arg&quot;</span> <span class="hljs-keyword">in</span> kwargs:
            preprocess_kwargs[<span class="hljs-string">&quot;maybe_arg&quot;</span>] = kwargs[<span class="hljs-string">&quot;maybe_arg&quot;</span>]
        <span class="hljs-keyword">return</span> preprocess_kwargs, {}, {}

    <span class="hljs-keyword">def</span> <span class="hljs-title function_">preprocess</span>(<span class="hljs-params">self, inputs, maybe_arg=<span class="hljs-number">2</span></span>):
        model_input = Tensor(inputs[<span class="hljs-string">&quot;input_ids&quot;</span>])
        <span class="hljs-keyword">return</span> {<span class="hljs-string">&quot;model_input&quot;</span>: model_input}

    <span class="hljs-keyword">def</span> <span class="hljs-title function_">_forward</span>(<span class="hljs-params">self, model_inputs</span>):
        <span class="hljs-comment"># model_inputs == {&quot;model_input&quot;: model_input}</span>
        outputs = self.model(**model_inputs)
        <span class="hljs-comment"># Maybe {&quot;logits&quot;: Tensor(...)}</span>
        <span class="hljs-keyword">return</span> outputs

    <span class="hljs-keyword">def</span> <span class="hljs-title function_">postprocess</span>(<span class="hljs-params">self, model_outputs</span>):
        best_class = model_outputs[<span class="hljs-string">&quot;logits&quot;</span>].softmax(-<span class="hljs-number">1</span>)
        <span class="hljs-keyword">return</span> best_class`}}),F=new Qa({props:{code:`pipe = pipeline("my-new-task")
pipe("This is a test")

pipe("This is a test", top_k=2)`,highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span>pipe = pipeline(<span class="hljs-string">&quot;my-new-task&quot;</span>)
<span class="hljs-meta">&gt;&gt;&gt; </span>pipe(<span class="hljs-string">&quot;This is a test&quot;</span>)
[{<span class="hljs-string">&quot;label&quot;</span>: <span class="hljs-string">&quot;1-star&quot;</span>, <span class="hljs-string">&quot;score&quot;</span>: <span class="hljs-number">0.8</span>}, {<span class="hljs-string">&quot;label&quot;</span>: <span class="hljs-string">&quot;2-star&quot;</span>, <span class="hljs-string">&quot;score&quot;</span>: <span class="hljs-number">0.1</span>}, {<span class="hljs-string">&quot;label&quot;</span>: <span class="hljs-string">&quot;3-star&quot;</span>, <span class="hljs-string">&quot;score&quot;</span>: <span class="hljs-number">0.05</span>}
{<span class="hljs-string">&quot;label&quot;</span>: <span class="hljs-string">&quot;4-star&quot;</span>, <span class="hljs-string">&quot;score&quot;</span>: <span class="hljs-number">0.025</span>}, {<span class="hljs-string">&quot;label&quot;</span>: <span class="hljs-string">&quot;5-star&quot;</span>, <span class="hljs-string">&quot;score&quot;</span>: <span class="hljs-number">0.025</span>}]

<span class="hljs-meta">&gt;&gt;&gt; </span>pipe(<span class="hljs-string">&quot;This is a test&quot;</span>, top_k=<span class="hljs-number">2</span>)
[{<span class="hljs-string">&quot;label&quot;</span>: <span class="hljs-string">&quot;1-star&quot;</span>, <span class="hljs-string">&quot;score&quot;</span>: <span class="hljs-number">0.8</span>}, {<span class="hljs-string">&quot;label&quot;</span>: <span class="hljs-string">&quot;2-star&quot;</span>, <span class="hljs-string">&quot;score&quot;</span>: <span class="hljs-number">0.1</span>}]`}}),K=new Qa({props:{code:`def postprocess(self, model_outputs, top_k=5):
    best_class = model_outputs["logits"].softmax(-1)
    # Add logic to handle top_k
    return best_class


def _sanitize_parameters(self, **kwargs):
    preprocess_kwargs = {}
    if "maybe_arg" in kwargs:
        preprocess_kwargs["maybe_arg"] = kwargs["maybe_arg"]

    postprocess_kwargs = {}
    if "top_k" in kwargs:
        preprocess_kwargs["top_k"] = kwargs["top_k"]
    return preprocess_kwargs, {}, postprocess_kwargs`,highlighted:`<span class="hljs-keyword">def</span> <span class="hljs-title function_">postprocess</span>(<span class="hljs-params">self, model_outputs, top_k=<span class="hljs-number">5</span></span>):
    best_class = model_outputs[<span class="hljs-string">&quot;logits&quot;</span>].softmax(-<span class="hljs-number">1</span>)
    <span class="hljs-comment"># Add logic to handle top_k</span>
    <span class="hljs-keyword">return</span> best_class


<span class="hljs-keyword">def</span> <span class="hljs-title function_">_sanitize_parameters</span>(<span class="hljs-params">self, **kwargs</span>):
    preprocess_kwargs = {}
    <span class="hljs-keyword">if</span> <span class="hljs-string">&quot;maybe_arg&quot;</span> <span class="hljs-keyword">in</span> kwargs:
        preprocess_kwargs[<span class="hljs-string">&quot;maybe_arg&quot;</span>] = kwargs[<span class="hljs-string">&quot;maybe_arg&quot;</span>]

    postprocess_kwargs = {}
    <span class="hljs-keyword">if</span> <span class="hljs-string">&quot;top_k&quot;</span> <span class="hljs-keyword">in</span> kwargs:
        preprocess_kwargs[<span class="hljs-string">&quot;top_k&quot;</span>] = kwargs[<span class="hljs-string">&quot;top_k&quot;</span>]
    <span class="hljs-keyword">return</span> preprocess_kwargs, {}, postprocess_kwargs`}}),Q=new Ka({}),V=new Ka({}),{c(){C=l("meta"),fs=d(),D=l("h1"),A=l("a"),ce=l("span"),le(R.$$.fragment),Js=d(),he=l("span"),Rs=a("How to add a pipeline to \u{1F917} Transformers?"),ms=d(),E=l("p"),Bs=a(`First and foremost, you need to decide the raw entries the pipeline will be able to take. It can be strings, raw bytes,
dictionaries or whatever seems to be the most likely desired input. Try to keep these inputs as pure Python as possible
as it makes compatibility easier (even through other languages via JSON). Those will be the `),ue=l("code"),Fs=a("inputs"),Ks=a(` of the
pipeline (`),fe=l("code"),Qs=a("preprocess"),Vs=a(")."),_s=d(),m=l("p"),Ws=a("Then define the "),me=l("code"),Zs=a("outputs"),et=a(". Same policy as the "),_e=l("code"),st=a("inputs"),tt=a(`. The simpler, the better. Those will be the outputs of
`),we=l("code"),at=a("postprocess"),ot=a(" method."),ws=d(),h=l("p"),lt=a("Start by inheriting the base class "),ye=l("code"),rt=a("Pipeline"),nt=a(". with the 4 methods needed to implement "),ke=l("code"),pt=a("preprocess"),it=a(`,
`),ve=l("code"),dt=a("_forward"),ct=a(", "),ge=l("code"),ht=a("postprocess"),ut=a(" and "),Ee=l("code"),ft=a("_sanitize_parameters"),mt=a("."),ys=d(),le(B.$$.fragment),ks=d(),ee=l("p"),_t=a(`The structure of this breakdown is to support relatively seamless support for CPU/GPU, while supporting doing
pre/postprocessing on the CPU on different threads`),vs=d(),T=l("p"),be=l("code"),wt=a("preprocess"),yt=a(` will take the originally defined inputs, and turn them into something feedable to the model. It might
contain more information and is usually a `),je=l("code"),kt=a("Dict"),vt=a("."),gs=d(),v=l("p"),qe=l("code"),gt=a("_forward"),Et=a(" is the implementation detail and is not meant to be called directly. "),Ce=l("code"),bt=a("forward"),jt=a(` is the preferred
called method as it contains safeguards to make sure everything is working on the expected device. If anything is
linked to a real model it belongs in the `),De=l("code"),qt=a("_forward"),Ct=a(" method, anything else is in the preprocess/postprocess."),Es=d(),P=l("p"),Te=l("code"),Dt=a("postprocess"),Tt=a(" methods will take the output of "),Pe=l("code"),Pt=a("_forward"),Ot=a(` and turn it into the final output that were decided
earlier.`),bs=d(),g=l("p"),Oe=l("code"),$t=a("_sanitize_parameters"),At=a(` exists to allow users to pass any parameters whenever they wish, be it at initialization
time `),$e=l("code"),St=a("pipeline(...., maybe_arg=4)"),xt=a(" or at call time "),Ae=l("code"),It=a("pipe = pipeline(...); output = pipe(...., maybe_arg=4)"),zt=a("."),js=d(),u=l("p"),Nt=a("The returns of "),Se=l("code"),Lt=a("_sanitize_parameters"),Ut=a(" are the 3 dicts of kwargs that will be passed directly to "),xe=l("code"),Ht=a("preprocess"),Mt=a(`,
`),Ie=l("code"),Yt=a("_forward"),Xt=a(" and "),ze=l("code"),Gt=a("postprocess"),Jt=a(`. Don\u2019t fill anything if the caller didn\u2019t call with any extra parameter. That
allows to keep the default arguments in the function definition which is always more \u201Cnatural\u201D.`),qs=d(),S=l("p"),Rt=a("A classic example would be a "),Ne=l("code"),Bt=a("top_k"),Ft=a(" argument in the post processing in classification tasks."),Cs=d(),le(F.$$.fragment),Ds=d(),_=l("p"),Kt=a("In order to achieve that, we\u2019ll update our "),Le=l("code"),Qt=a("postprocess"),Vt=a(" method with a default parameter to "),Ue=l("code"),Wt=a("5"),Zt=a(`. and edit
`),He=l("code"),ea=a("_sanitize_parameters"),sa=a(" to allow this new parameter."),Ts=d(),le(K.$$.fragment),Ps=d(),se=l("p"),ta=a(`Try to keep the inputs/outputs very simple and ideally JSON-serializable as it makes the pipeline usage very easy
without requiring users to understand new kind of objects. It\u2019s also relatively common to support many different types
of arguments for ease of use (audio files, can be filenames, URLs or pure bytes)`),Os=d(),O=l("h2"),x=l("a"),Me=l("span"),le(Q.$$.fragment),aa=d(),Ye=l("span"),oa=a("Adding it to the list of supported tasks"),$s=d(),b=l("p"),la=a("Go to "),Xe=l("code"),ra=a("src/transformers/pipelines/__init__.py"),na=a(" and fill in "),Ge=l("code"),pa=a("SUPPORTED_TASKS"),ia=a(` with your newly created pipeline.
If possible it should provide a default model.`),As=d(),$=l("h2"),I=l("a"),Je=l("span"),le(V.$$.fragment),da=d(),Re=l("span"),ca=a("Adding tests"),Ss=d(),z=l("p"),ha=a("Create a new file "),Be=l("code"),ua=a("tests/test_pipelines_MY_PIPELINE.py"),fa=a(" with example with the other tests."),xs=d(),w=l("p"),ma=a("The "),Fe=l("code"),_a=a("run_pipeline_test"),wa=a(` function will be very generic and run on small random models on every possible
architecture as defined by `),Ke=l("code"),ya=a("model_mapping"),ka=a(" and "),Qe=l("code"),va=a("tf_model_mapping"),ga=a("."),Is=d(),j=l("p"),Ea=a(`This is very important to test future compatibility, meaning if someone adds a new model for
`),Ve=l("code"),ba=a("XXXForQuestionAnswering"),ja=a(` then the pipeline test will attempt to run on it. Because the models are random it\u2019s
impossible to check for actual values, that\u2019s why There is a helper `),We=l("code"),qa=a("ANY"),Ca=a(` that will simply attempt to match the
output of the pipeline TYPE.`),zs=d(),N=l("p"),Da=a("You also "),Ze=l("em"),Ta=a("need"),Pa=a(" to implement 2 (ideally 4) tests."),Ns=d(),y=l("ul"),L=l("li"),es=l("code"),Oa=a("test_small_model_pt"),$a=a(` : Define 1 small model for this pipeline (doesn\u2019t matter if the results don\u2019t make sense)
and test the pipeline outputs. The results should be the same as `),ss=l("code"),Aa=a("test_small_model_tf"),Sa=a("."),xa=d(),U=l("li"),ts=l("code"),Ia=a("test_small_model_tf"),za=a(` : Define 1 small model for this pipeline (doesn\u2019t matter if the results don\u2019t make sense)
and test the pipeline outputs. The results should be the same as `),as=l("code"),Na=a("test_small_model_pt"),La=a("."),Ua=d(),H=l("li"),os=l("code"),Ha=a("test_large_model_pt"),Ma=a(" ("),ls=l("code"),Ya=a("optional"),Xa=a(`): Tests the pipeline on a real pipeline where the results are supposed to
make sense. These tests are slow and should be marked as such. Here the goal is to showcase the pipeline and to make
sure there is no drift in future releases`),Ga=d(),M=l("li"),rs=l("code"),Ja=a("test_large_model_tf"),Ra=a(" ("),ns=l("code"),Ba=a("optional"),Fa=a(`): Tests the pipeline on a real pipeline where the results are supposed to
make sense. These tests are slow and should be marked as such. Here the goal is to showcase the pipeline and to make
sure there is no drift in future releases`),this.h()},l(s){const p=ol('[data-svelte="svelte-1phssyn"]',document.head);C=r(p,"META",{name:!0,content:!0}),p.forEach(t),fs=c(s),D=r(s,"H1",{class:!0});var Us=n(D);A=r(Us,"A",{id:!0,class:!0,href:!0});var Wa=n(A);ce=r(Wa,"SPAN",{});var Za=n(ce);re(R.$$.fragment,Za),Za.forEach(t),Wa.forEach(t),Js=c(Us),he=r(Us,"SPAN",{});var eo=n(he);Rs=o(eo,"How to add a pipeline to \u{1F917} Transformers?"),eo.forEach(t),Us.forEach(t),ms=c(s),E=r(s,"P",{});var te=n(E);Bs=o(te,`First and foremost, you need to decide the raw entries the pipeline will be able to take. It can be strings, raw bytes,
dictionaries or whatever seems to be the most likely desired input. Try to keep these inputs as pure Python as possible
as it makes compatibility easier (even through other languages via JSON). Those will be the `),ue=r(te,"CODE",{});var so=n(ue);Fs=o(so,"inputs"),so.forEach(t),Ks=o(te,` of the
pipeline (`),fe=r(te,"CODE",{});var to=n(fe);Qs=o(to,"preprocess"),to.forEach(t),Vs=o(te,")."),te.forEach(t),_s=c(s),m=r(s,"P",{});var Y=n(m);Ws=o(Y,"Then define the "),me=r(Y,"CODE",{});var ao=n(me);Zs=o(ao,"outputs"),ao.forEach(t),et=o(Y,". Same policy as the "),_e=r(Y,"CODE",{});var oo=n(_e);st=o(oo,"inputs"),oo.forEach(t),tt=o(Y,`. The simpler, the better. Those will be the outputs of
`),we=r(Y,"CODE",{});var lo=n(we);at=o(lo,"postprocess"),lo.forEach(t),ot=o(Y," method."),Y.forEach(t),ws=c(s),h=r(s,"P",{});var k=n(h);lt=o(k,"Start by inheriting the base class "),ye=r(k,"CODE",{});var ro=n(ye);rt=o(ro,"Pipeline"),ro.forEach(t),nt=o(k,". with the 4 methods needed to implement "),ke=r(k,"CODE",{});var no=n(ke);pt=o(no,"preprocess"),no.forEach(t),it=o(k,`,
`),ve=r(k,"CODE",{});var po=n(ve);dt=o(po,"_forward"),po.forEach(t),ct=o(k,", "),ge=r(k,"CODE",{});var io=n(ge);ht=o(io,"postprocess"),io.forEach(t),ut=o(k," and "),Ee=r(k,"CODE",{});var co=n(Ee);ft=o(co,"_sanitize_parameters"),co.forEach(t),mt=o(k,"."),k.forEach(t),ys=c(s),re(B.$$.fragment,s),ks=c(s),ee=r(s,"P",{});var ho=n(ee);_t=o(ho,`The structure of this breakdown is to support relatively seamless support for CPU/GPU, while supporting doing
pre/postprocessing on the CPU on different threads`),ho.forEach(t),vs=c(s),T=r(s,"P",{});var ps=n(T);be=r(ps,"CODE",{});var uo=n(be);wt=o(uo,"preprocess"),uo.forEach(t),yt=o(ps,` will take the originally defined inputs, and turn them into something feedable to the model. It might
contain more information and is usually a `),je=r(ps,"CODE",{});var fo=n(je);kt=o(fo,"Dict"),fo.forEach(t),vt=o(ps,"."),ps.forEach(t),gs=c(s),v=r(s,"P",{});var W=n(v);qe=r(W,"CODE",{});var mo=n(qe);gt=o(mo,"_forward"),mo.forEach(t),Et=o(W," is the implementation detail and is not meant to be called directly. "),Ce=r(W,"CODE",{});var _o=n(Ce);bt=o(_o,"forward"),_o.forEach(t),jt=o(W,` is the preferred
called method as it contains safeguards to make sure everything is working on the expected device. If anything is
linked to a real model it belongs in the `),De=r(W,"CODE",{});var wo=n(De);qt=o(wo,"_forward"),wo.forEach(t),Ct=o(W," method, anything else is in the preprocess/postprocess."),W.forEach(t),Es=c(s),P=r(s,"P",{});var is=n(P);Te=r(is,"CODE",{});var yo=n(Te);Dt=o(yo,"postprocess"),yo.forEach(t),Tt=o(is," methods will take the output of "),Pe=r(is,"CODE",{});var ko=n(Pe);Pt=o(ko,"_forward"),ko.forEach(t),Ot=o(is,` and turn it into the final output that were decided
earlier.`),is.forEach(t),bs=c(s),g=r(s,"P",{});var Z=n(g);Oe=r(Z,"CODE",{});var vo=n(Oe);$t=o(vo,"_sanitize_parameters"),vo.forEach(t),At=o(Z,` exists to allow users to pass any parameters whenever they wish, be it at initialization
time `),$e=r(Z,"CODE",{});var go=n($e);St=o(go,"pipeline(...., maybe_arg=4)"),go.forEach(t),xt=o(Z," or at call time "),Ae=r(Z,"CODE",{});var Eo=n(Ae);It=o(Eo,"pipe = pipeline(...); output = pipe(...., maybe_arg=4)"),Eo.forEach(t),zt=o(Z,"."),Z.forEach(t),js=c(s),u=r(s,"P",{});var q=n(u);Nt=o(q,"The returns of "),Se=r(q,"CODE",{});var bo=n(Se);Lt=o(bo,"_sanitize_parameters"),bo.forEach(t),Ut=o(q," are the 3 dicts of kwargs that will be passed directly to "),xe=r(q,"CODE",{});var jo=n(xe);Ht=o(jo,"preprocess"),jo.forEach(t),Mt=o(q,`,
`),Ie=r(q,"CODE",{});var qo=n(Ie);Yt=o(qo,"_forward"),qo.forEach(t),Xt=o(q," and "),ze=r(q,"CODE",{});var Co=n(ze);Gt=o(Co,"postprocess"),Co.forEach(t),Jt=o(q,`. Don\u2019t fill anything if the caller didn\u2019t call with any extra parameter. That
allows to keep the default arguments in the function definition which is always more \u201Cnatural\u201D.`),q.forEach(t),qs=c(s),S=r(s,"P",{});var Hs=n(S);Rt=o(Hs,"A classic example would be a "),Ne=r(Hs,"CODE",{});var Do=n(Ne);Bt=o(Do,"top_k"),Do.forEach(t),Ft=o(Hs," argument in the post processing in classification tasks."),Hs.forEach(t),Cs=c(s),re(F.$$.fragment,s),Ds=c(s),_=r(s,"P",{});var X=n(_);Kt=o(X,"In order to achieve that, we\u2019ll update our "),Le=r(X,"CODE",{});var To=n(Le);Qt=o(To,"postprocess"),To.forEach(t),Vt=o(X," method with a default parameter to "),Ue=r(X,"CODE",{});var Po=n(Ue);Wt=o(Po,"5"),Po.forEach(t),Zt=o(X,`. and edit
`),He=r(X,"CODE",{});var Oo=n(He);ea=o(Oo,"_sanitize_parameters"),Oo.forEach(t),sa=o(X," to allow this new parameter."),X.forEach(t),Ts=c(s),re(K.$$.fragment,s),Ps=c(s),se=r(s,"P",{});var $o=n(se);ta=o($o,`Try to keep the inputs/outputs very simple and ideally JSON-serializable as it makes the pipeline usage very easy
without requiring users to understand new kind of objects. It\u2019s also relatively common to support many different types
of arguments for ease of use (audio files, can be filenames, URLs or pure bytes)`),$o.forEach(t),Os=c(s),O=r(s,"H2",{class:!0});var Ms=n(O);x=r(Ms,"A",{id:!0,class:!0,href:!0});var Ao=n(x);Me=r(Ao,"SPAN",{});var So=n(Me);re(Q.$$.fragment,So),So.forEach(t),Ao.forEach(t),aa=c(Ms),Ye=r(Ms,"SPAN",{});var xo=n(Ye);oa=o(xo,"Adding it to the list of supported tasks"),xo.forEach(t),Ms.forEach(t),$s=c(s),b=r(s,"P",{});var ae=n(b);la=o(ae,"Go to "),Xe=r(ae,"CODE",{});var Io=n(Xe);ra=o(Io,"src/transformers/pipelines/__init__.py"),Io.forEach(t),na=o(ae," and fill in "),Ge=r(ae,"CODE",{});var zo=n(Ge);pa=o(zo,"SUPPORTED_TASKS"),zo.forEach(t),ia=o(ae,` with your newly created pipeline.
If possible it should provide a default model.`),ae.forEach(t),As=c(s),$=r(s,"H2",{class:!0});var Ys=n($);I=r(Ys,"A",{id:!0,class:!0,href:!0});var No=n(I);Je=r(No,"SPAN",{});var Lo=n(Je);re(V.$$.fragment,Lo),Lo.forEach(t),No.forEach(t),da=c(Ys),Re=r(Ys,"SPAN",{});var Uo=n(Re);ca=o(Uo,"Adding tests"),Uo.forEach(t),Ys.forEach(t),Ss=c(s),z=r(s,"P",{});var Xs=n(z);ha=o(Xs,"Create a new file "),Be=r(Xs,"CODE",{});var Ho=n(Be);ua=o(Ho,"tests/test_pipelines_MY_PIPELINE.py"),Ho.forEach(t),fa=o(Xs," with example with the other tests."),Xs.forEach(t),xs=c(s),w=r(s,"P",{});var G=n(w);ma=o(G,"The "),Fe=r(G,"CODE",{});var Mo=n(Fe);_a=o(Mo,"run_pipeline_test"),Mo.forEach(t),wa=o(G,` function will be very generic and run on small random models on every possible
architecture as defined by `),Ke=r(G,"CODE",{});var Yo=n(Ke);ya=o(Yo,"model_mapping"),Yo.forEach(t),ka=o(G," and "),Qe=r(G,"CODE",{});var Xo=n(Qe);va=o(Xo,"tf_model_mapping"),Xo.forEach(t),ga=o(G,"."),G.forEach(t),Is=c(s),j=r(s,"P",{});var oe=n(j);Ea=o(oe,`This is very important to test future compatibility, meaning if someone adds a new model for
`),Ve=r(oe,"CODE",{});var Go=n(Ve);ba=o(Go,"XXXForQuestionAnswering"),Go.forEach(t),ja=o(oe,` then the pipeline test will attempt to run on it. Because the models are random it\u2019s
impossible to check for actual values, that\u2019s why There is a helper `),We=r(oe,"CODE",{});var Jo=n(We);qa=o(Jo,"ANY"),Jo.forEach(t),Ca=o(oe,` that will simply attempt to match the
output of the pipeline TYPE.`),oe.forEach(t),zs=c(s),N=r(s,"P",{});var Gs=n(N);Da=o(Gs,"You also "),Ze=r(Gs,"EM",{});var Ro=n(Ze);Ta=o(Ro,"need"),Ro.forEach(t),Pa=o(Gs," to implement 2 (ideally 4) tests."),Gs.forEach(t),Ns=c(s),y=r(s,"UL",{});var J=n(y);L=r(J,"LI",{});var ds=n(L);es=r(ds,"CODE",{});var Bo=n(es);Oa=o(Bo,"test_small_model_pt"),Bo.forEach(t),$a=o(ds,` : Define 1 small model for this pipeline (doesn\u2019t matter if the results don\u2019t make sense)
and test the pipeline outputs. The results should be the same as `),ss=r(ds,"CODE",{});var Fo=n(ss);Aa=o(Fo,"test_small_model_tf"),Fo.forEach(t),Sa=o(ds,"."),ds.forEach(t),xa=c(J),U=r(J,"LI",{});var cs=n(U);ts=r(cs,"CODE",{});var Ko=n(ts);Ia=o(Ko,"test_small_model_tf"),Ko.forEach(t),za=o(cs,` : Define 1 small model for this pipeline (doesn\u2019t matter if the results don\u2019t make sense)
and test the pipeline outputs. The results should be the same as `),as=r(cs,"CODE",{});var Qo=n(as);Na=o(Qo,"test_small_model_pt"),Qo.forEach(t),La=o(cs,"."),cs.forEach(t),Ua=c(J),H=r(J,"LI",{});var hs=n(H);os=r(hs,"CODE",{});var Vo=n(os);Ha=o(Vo,"test_large_model_pt"),Vo.forEach(t),Ma=o(hs," ("),ls=r(hs,"CODE",{});var Wo=n(ls);Ya=o(Wo,"optional"),Wo.forEach(t),Xa=o(hs,`): Tests the pipeline on a real pipeline where the results are supposed to
make sense. These tests are slow and should be marked as such. Here the goal is to showcase the pipeline and to make
sure there is no drift in future releases`),hs.forEach(t),Ga=c(J),M=r(J,"LI",{});var us=n(M);rs=r(us,"CODE",{});var Zo=n(rs);Ja=o(Zo,"test_large_model_tf"),Zo.forEach(t),Ra=o(us," ("),ns=r(us,"CODE",{});var el=n(ns);Ba=o(el,"optional"),el.forEach(t),Fa=o(us,`): Tests the pipeline on a real pipeline where the results are supposed to
make sense. These tests are slow and should be marked as such. Here the goal is to showcase the pipeline and to make
sure there is no drift in future releases`),us.forEach(t),J.forEach(t),this.h()},h(){f(C,"name","hf:doc:metadata"),f(C,"content",JSON.stringify(pl)),f(A,"id","how-to-add-a-pipeline-to-transformers"),f(A,"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"),f(A,"href","#how-to-add-a-pipeline-to-transformers"),f(D,"class","relative group"),f(x,"id","adding-it-to-the-list-of-supported-tasks"),f(x,"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"),f(x,"href","#adding-it-to-the-list-of-supported-tasks"),f(O,"class","relative group"),f(I,"id","adding-tests"),f(I,"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"),f(I,"href","#adding-tests"),f($,"class","relative group")},m(s,p){e(document.head,C),i(s,fs,p),i(s,D,p),e(D,A),e(A,ce),ne(R,ce,null),e(D,Js),e(D,he),e(he,Rs),i(s,ms,p),i(s,E,p),e(E,Bs),e(E,ue),e(ue,Fs),e(E,Ks),e(E,fe),e(fe,Qs),e(E,Vs),i(s,_s,p),i(s,m,p),e(m,Ws),e(m,me),e(me,Zs),e(m,et),e(m,_e),e(_e,st),e(m,tt),e(m,we),e(we,at),e(m,ot),i(s,ws,p),i(s,h,p),e(h,lt),e(h,ye),e(ye,rt),e(h,nt),e(h,ke),e(ke,pt),e(h,it),e(h,ve),e(ve,dt),e(h,ct),e(h,ge),e(ge,ht),e(h,ut),e(h,Ee),e(Ee,ft),e(h,mt),i(s,ys,p),ne(B,s,p),i(s,ks,p),i(s,ee,p),e(ee,_t),i(s,vs,p),i(s,T,p),e(T,be),e(be,wt),e(T,yt),e(T,je),e(je,kt),e(T,vt),i(s,gs,p),i(s,v,p),e(v,qe),e(qe,gt),e(v,Et),e(v,Ce),e(Ce,bt),e(v,jt),e(v,De),e(De,qt),e(v,Ct),i(s,Es,p),i(s,P,p),e(P,Te),e(Te,Dt),e(P,Tt),e(P,Pe),e(Pe,Pt),e(P,Ot),i(s,bs,p),i(s,g,p),e(g,Oe),e(Oe,$t),e(g,At),e(g,$e),e($e,St),e(g,xt),e(g,Ae),e(Ae,It),e(g,zt),i(s,js,p),i(s,u,p),e(u,Nt),e(u,Se),e(Se,Lt),e(u,Ut),e(u,xe),e(xe,Ht),e(u,Mt),e(u,Ie),e(Ie,Yt),e(u,Xt),e(u,ze),e(ze,Gt),e(u,Jt),i(s,qs,p),i(s,S,p),e(S,Rt),e(S,Ne),e(Ne,Bt),e(S,Ft),i(s,Cs,p),ne(F,s,p),i(s,Ds,p),i(s,_,p),e(_,Kt),e(_,Le),e(Le,Qt),e(_,Vt),e(_,Ue),e(Ue,Wt),e(_,Zt),e(_,He),e(He,ea),e(_,sa),i(s,Ts,p),ne(K,s,p),i(s,Ps,p),i(s,se,p),e(se,ta),i(s,Os,p),i(s,O,p),e(O,x),e(x,Me),ne(Q,Me,null),e(O,aa),e(O,Ye),e(Ye,oa),i(s,$s,p),i(s,b,p),e(b,la),e(b,Xe),e(Xe,ra),e(b,na),e(b,Ge),e(Ge,pa),e(b,ia),i(s,As,p),i(s,$,p),e($,I),e(I,Je),ne(V,Je,null),e($,da),e($,Re),e(Re,ca),i(s,Ss,p),i(s,z,p),e(z,ha),e(z,Be),e(Be,ua),e(z,fa),i(s,xs,p),i(s,w,p),e(w,ma),e(w,Fe),e(Fe,_a),e(w,wa),e(w,Ke),e(Ke,ya),e(w,ka),e(w,Qe),e(Qe,va),e(w,ga),i(s,Is,p),i(s,j,p),e(j,Ea),e(j,Ve),e(Ve,ba),e(j,ja),e(j,We),e(We,qa),e(j,Ca),i(s,zs,p),i(s,N,p),e(N,Da),e(N,Ze),e(Ze,Ta),e(N,Pa),i(s,Ns,p),i(s,y,p),e(y,L),e(L,es),e(es,Oa),e(L,$a),e(L,ss),e(ss,Aa),e(L,Sa),e(y,xa),e(y,U),e(U,ts),e(ts,Ia),e(U,za),e(U,as),e(as,Na),e(U,La),e(y,Ua),e(y,H),e(H,os),e(os,Ha),e(H,Ma),e(H,ls),e(ls,Ya),e(H,Xa),e(y,Ga),e(y,M),e(M,rs),e(rs,Ja),e(M,Ra),e(M,ns),e(ns,Ba),e(M,Fa),Ls=!0},p:ll,i(s){Ls||(pe(R.$$.fragment,s),pe(B.$$.fragment,s),pe(F.$$.fragment,s),pe(K.$$.fragment,s),pe(Q.$$.fragment,s),pe(V.$$.fragment,s),Ls=!0)},o(s){ie(R.$$.fragment,s),ie(B.$$.fragment,s),ie(F.$$.fragment,s),ie(K.$$.fragment,s),ie(Q.$$.fragment,s),ie(V.$$.fragment,s),Ls=!1},d(s){t(C),s&&t(fs),s&&t(D),de(R),s&&t(ms),s&&t(E),s&&t(_s),s&&t(m),s&&t(ws),s&&t(h),s&&t(ys),de(B,s),s&&t(ks),s&&t(ee),s&&t(vs),s&&t(T),s&&t(gs),s&&t(v),s&&t(Es),s&&t(P),s&&t(bs),s&&t(g),s&&t(js),s&&t(u),s&&t(qs),s&&t(S),s&&t(Cs),de(F,s),s&&t(Ds),s&&t(_),s&&t(Ts),de(K,s),s&&t(Ps),s&&t(se),s&&t(Os),s&&t(O),de(Q),s&&t($s),s&&t(b),s&&t(As),s&&t($),de(V),s&&t(Ss),s&&t(z),s&&t(xs),s&&t(w),s&&t(Is),s&&t(j),s&&t(zs),s&&t(N),s&&t(Ns),s&&t(y)}}}const pl={local:"how-to-add-a-pipeline-to-transformers",sections:[{local:"adding-it-to-the-list-of-supported-tasks",title:"Adding it to the list of supported tasks"},{local:"adding-tests",title:"Adding tests"}],title:"How to add a pipeline to \u{1F917} Transformers?"};function il(Va){return rl(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class ul extends sl{constructor(C){super();tl(this,C,il,nl,al,{})}}export{ul as default,pl as metadata};
