Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Generation strategies","local":"generation-strategies","sections":[{"title":"Basic decoding methods","local":"basic-decoding-methods","sections":[{"title":"Greedy search","local":"greedy-search","sections":[],"depth":3},{"title":"Sampling","local":"sampling","sections":[],"depth":3},{"title":"Beam search","local":"beam-search","sections":[],"depth":3}],"depth":2},{"title":"Custom generation methods","local":"custom-generation-methods","sections":[{"title":"Creating a custom generation method","local":"creating-a-custom-generation-method","sections":[{"title":"Adding the base model","local":"adding-the-base-model","sections":[],"depth":4},{"title":"generate.py","local":"generatepy","sections":[],"depth":4},{"title":"requirements.txt","local":"requirementstxt","sections":[],"depth":4},{"title":"README.md","local":"readmemd","sections":[],"depth":4}],"depth":3},{"title":"Reusing generate ’s input preparation","local":"reusing-generate-s-input-preparation","sections":[],"depth":3},{"title":"Finding custom generation methods","local":"finding-custom-generation-methods","sections":[],"depth":3}],"depth":2},{"title":"Resources","local":"resources","sections":[],"depth":2}],"depth":1}"> | |
| <link href="/docs/transformers/pr_43265/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/entry/start.1dae3980.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/chunks/scheduler.31fdf58d.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/chunks/singletons.5fcb8d34.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/chunks/index.252883d5.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/chunks/paths.e648cef5.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/entry/app.66dba7a3.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/chunks/preload-helper.5b8be175.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/chunks/index.2f76fdf0.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/nodes/0.4837e553.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/chunks/each.e59479a4.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/nodes/53.828ddfd4.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/chunks/CopyLLMTxtMenu.53b607bf.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/chunks/MermaidChart.svelte_svelte_type_style_lang.08750ec0.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/chunks/IconCopy.ac192424.js"> | |
| <link rel="modulepreload" href="/docs/transformers/pr_43265/en/_app/immutable/chunks/CodeBlock.e52df5d6.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{"title":"Generation strategies","local":"generation-strategies","sections":[{"title":"Basic decoding methods","local":"basic-decoding-methods","sections":[{"title":"Greedy search","local":"greedy-search","sections":[],"depth":3},{"title":"Sampling","local":"sampling","sections":[],"depth":3},{"title":"Beam search","local":"beam-search","sections":[],"depth":3}],"depth":2},{"title":"Custom generation methods","local":"custom-generation-methods","sections":[{"title":"Creating a custom generation method","local":"creating-a-custom-generation-method","sections":[{"title":"Adding the base model","local":"adding-the-base-model","sections":[],"depth":4},{"title":"generate.py","local":"generatepy","sections":[],"depth":4},{"title":"requirements.txt","local":"requirementstxt","sections":[],"depth":4},{"title":"README.md","local":"readmemd","sections":[],"depth":4}],"depth":3},{"title":"Reusing generate ’s input preparation","local":"reusing-generate-s-input-preparation","sections":[],"depth":3},{"title":"Finding custom generation methods","local":"finding-custom-generation-methods","sections":[],"depth":3}],"depth":2},{"title":"Resources","local":"resources","sections":[],"depth":2}],"depth":1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg></button></div> </div> <h1 class="relative group"><a id="generation-strategies" 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" href="#generation-strategies"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Generation strategies</span></h1> <p data-svelte-h="svelte-mu4vht">A decoding strategy informs how a model should select the next generated token. There are many types of decoding strategies, and choosing the appropriate one has a significant impact on the quality of the generated text.</p> <p data-svelte-h="svelte-14bli3k">This guide will help you understand the different decoding strategies available in Transformers and how and when to use them.</p> <h2 class="relative group"><a id="basic-decoding-methods" 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" href="#basic-decoding-methods"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Basic decoding methods</span></h2> <p data-svelte-h="svelte-i7eisu">These are well established decoding methods, and should be your starting point for text generation tasks.</p> <h3 class="relative group"><a id="greedy-search" 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" href="#greedy-search"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Greedy search</span></h3> <p data-svelte-h="svelte-1e3qran">Greedy search is the default decoding strategy. It selects the next most likely token at each step. Unless specified in <a href="/docs/transformers/pr_43265/en/main_classes/text_generation#transformers.GenerationConfig">GenerationConfig</a>, this strategy generates a maximum of 20 new tokens.</p> <p data-svelte-h="svelte-1mt54k3">Greedy search works well for tasks with relatively short outputs where creativity is not a priority. However, it breaks down when generating longer sequences because it begins to repeat itself.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-py "><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoModelForCausalLM, AutoTokenizer | |
| <span class="hljs-keyword">from</span> accelerate <span class="hljs-keyword">import</span> Accelerator | |
| device = Accelerator().device | |
| tokenizer = AutoTokenizer.from_pretrained(<span class="hljs-string">"meta-llama/Llama-2-7b-hf"</span>) | |
| inputs = tokenizer(<span class="hljs-string">"Hugging Face is an open-source company"</span>, return_tensors=<span class="hljs-string">"pt"</span>).to(device) | |
| model = AutoModelForCausalLM.from_pretrained(<span class="hljs-string">"meta-llama/Llama-2-7b-hf"</span>, dtype=torch.float16).to(device) | |
| <span class="hljs-comment"># explicitly set to default length because Llama2 generation length is 4096</span> | |
| outputs = model.generate(**inputs, max_new_tokens=<span class="hljs-number">20</span>) | |
| tokenizer.batch_decode(outputs, skip_special_tokens=<span class="hljs-literal">True</span>) | |
| <span class="hljs-string">'Hugging Face is an open-source company that provides a suite of tools and services for building, deploying, and maintaining natural language processing'</span><!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="sampling" 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" href="#sampling"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Sampling</span></h3> <p data-svelte-h="svelte-e4o6mk">Sampling, or multinomial sampling, randomly selects a token based on the probability distribution over the entire model’s vocabulary (as opposed to the most likely token, as in greedy search). This means every token with a non-zero probability has a chance to be selected. Sampling strategies reduce repetition and can generate more creative and diverse outputs.</p> <p data-svelte-h="svelte-1bwisky">Enable multinomial sampling with <code>do_sample=True</code> and <code>num_beams=1</code>.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-py "><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoModelForCausalLM, AutoTokenizer | |
| <span class="hljs-keyword">from</span> accelerate <span class="hljs-keyword">import</span> Accelerator | |
| device = Accelerator().device | |
| tokenizer = AutoTokenizer.from_pretrained(<span class="hljs-string">"meta-llama/Llama-2-7b-hf"</span>) | |
| inputs = tokenizer(<span class="hljs-string">"Hugging Face is an open-source company"</span>, return_tensors=<span class="hljs-string">"pt"</span>).to(device) | |
| model = AutoModelForCausalLM.from_pretrained(<span class="hljs-string">"meta-llama/Llama-2-7b-hf"</span>, dtype=torch.float16).to(device) | |
| <span class="hljs-comment"># explicitly set to 100 because Llama2 generation length is 4096</span> | |
| outputs = model.generate(**inputs, max_new_tokens=<span class="hljs-number">50</span>, do_sample=<span class="hljs-literal">True</span>, num_beams=<span class="hljs-number">1</span>) | |
| tokenizer.batch_decode(outputs, skip_special_tokens=<span class="hljs-literal">True</span>) | |
| <span class="hljs-string">'Hugging Face is an open-source company 🤗\nWe are open-source and believe that open-source is the best way to build technology. Our mission is to make AI accessible to everyone, and we believe that open-source is the best way to achieve that.'</span><!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="beam-search" 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" href="#beam-search"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Beam search</span></h3> <p data-svelte-h="svelte-licetj">Beam search keeps track of several generated sequences (beams) at each time step. After a certain number of steps, it selects the sequence with the highest <em>overall</em> probability. Unlike greedy search, this strategy can “look ahead” and pick a sequence with a higher probability overall even if the initial tokens have a lower probability. It is best suited for input-grounded tasks, like describing an image or speech recognition. You can also use <code>do_sample=True</code> with beam search to sample at each step, but beam search will still greedily prune out low probability sequences between steps.</p> <blockquote class="tip" data-svelte-h="svelte-1fj1l0j"><p>Check out the <a href="https://huggingface.co/spaces/m-ric/beam_search_visualizer" rel="nofollow">beam search visualizer</a> to see how beam search works.</p></blockquote> <p data-svelte-h="svelte-odkbop">Enable beam search with the <code>num_beams</code> parameter (should be greater than 1 otherwise it’s equivalent to greedy search).</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-py "><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoModelForCausalLM, AutoTokenizer | |
| <span class="hljs-keyword">from</span> accelerate <span class="hljs-keyword">import</span> Accelerator | |
| device = Accelerator().device | |
| tokenizer = AutoTokenizer.from_pretrained(<span class="hljs-string">"meta-llama/Llama-2-7b-hf"</span>) | |
| inputs = tokenizer(<span class="hljs-string">"Hugging Face is an open-source company"</span>, return_tensors=<span class="hljs-string">"pt"</span>).to(device) | |
| model = AutoModelForCausalLM.from_pretrained(<span class="hljs-string">"meta-llama/Llama-2-7b-hf"</span>, dtype=torch.float16).to(device) | |
| <span class="hljs-comment"># explicitly set to 100 because Llama2 generation length is 4096</span> | |
| outputs = model.generate(**inputs, max_new_tokens=<span class="hljs-number">50</span>, num_beams=<span class="hljs-number">2</span>) | |
| tokenizer.batch_decode(outputs, skip_special_tokens=<span class="hljs-literal">True</span>) | |
| <span class="hljs-string">"['Hugging Face is an open-source company that develops and maintains the Hugging Face platform, which is a collection of tools and libraries for building and deploying natural language processing (NLP) models. Hugging Face was founded in 2018 by Thomas Wolf']"</span><!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="custom-generation-methods" 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" href="#custom-generation-methods"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Custom generation methods</span></h2> <p data-svelte-h="svelte-8489ne">Custom generation methods enable specialized behavior such as:</p> <ul data-svelte-h="svelte-1kcz2qm"><li>have the model continue thinking if it is uncertain;</li> <li>roll back generation if the model gets stuck;</li> <li>handle special tokens with custom logic;</li> <li>use specialized KV caches;</li></ul> <p data-svelte-h="svelte-1vz3xu2">We enable custom generation methods through model repositories, assuming a specific model tag and file structure (see subsection below). This feature is an extension of <a href="./models#custom-models">custom modeling code</a> and, like such, requires setting <code>trust_remote_code=True</code>.</p> <p data-svelte-h="svelte-8y0a21">If a model repository holds a custom generation method, the easiest way to try it out is to load the model and generate with it:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-py "><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoModelForCausalLM, AutoTokenizer | |
| <span class="hljs-comment"># `transformers-community/custom_generate_example` holds a copy of `Qwen/Qwen2.5-0.5B-Instruct`, but</span> | |
| <span class="hljs-comment"># with custom generation code -> calling `generate` uses the custom generation method!</span> | |
| tokenizer = AutoTokenizer.from_pretrained(<span class="hljs-string">"transformers-community/custom_generate_example"</span>) | |
| model = AutoModelForCausalLM.from_pretrained( | |
| <span class="hljs-string">"transformers-community/custom_generate_example"</span>, device_map=<span class="hljs-string">"auto"</span>, trust_remote_code=<span class="hljs-literal">True</span> | |
| ) | |
| inputs = tokenizer([<span class="hljs-string">"The quick brown"</span>], return_tensors=<span class="hljs-string">"pt"</span>).to(model.device) | |
| <span class="hljs-comment"># The custom generation method is a minimal greedy decoding implementation. It also prints a custom message at run time.</span> | |
| gen_out = model.generate(**inputs) | |
| <span class="hljs-comment"># you should now see its custom message, "✨ using a custom generation method ✨"</span> | |
| <span class="hljs-built_in">print</span>(tokenizer.batch_decode(gen_out, skip_special_tokens=<span class="hljs-literal">True</span>)) | |
| <span class="hljs-string">'The quick brown fox jumps over a lazy dog, and the dog is a type of animal. Is'</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-7yd8pl">Model repositories with custom generation methods have a special property: their generation method can be loaded from <strong>any</strong> model through <a href="/docs/transformers/pr_43265/en/main_classes/text_generation#transformers.GenerationMixin.generate">generate()</a>’s <code>custom_generate</code> argument. This means anyone can create and share their custom generation method to potentially work with any Transformers model, without requiring users to install additional Python packages.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-py "><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoModelForCausalLM, AutoTokenizer | |
| tokenizer = AutoTokenizer.from_pretrained(<span class="hljs-string">"Qwen/Qwen2.5-0.5B-Instruct"</span>) | |
| model = AutoModelForCausalLM.from_pretrained(<span class="hljs-string">"Qwen/Qwen2.5-0.5B-Instruct"</span>, device_map=<span class="hljs-string">"auto"</span>) | |
| inputs = tokenizer([<span class="hljs-string">"The quick brown"</span>], return_tensors=<span class="hljs-string">"pt"</span>).to(model.device) | |
| <span class="hljs-comment"># `custom_generate` replaces the original `generate` by the custom generation method defined in</span> | |
| <span class="hljs-comment"># `transformers-community/custom_generate_example`</span> | |
| gen_out = model.generate(**inputs, custom_generate=<span class="hljs-string">"transformers-community/custom_generate_example"</span>, trust_remote_code=<span class="hljs-literal">True</span>) | |
| <span class="hljs-built_in">print</span>(tokenizer.batch_decode(gen_out, skip_special_tokens=<span class="hljs-literal">True</span>)[<span class="hljs-number">0</span>]) | |
| <span class="hljs-string">'The quick brown fox jumps over a lazy dog, and the dog is a type of animal. Is'</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-h5dnny">You should read the <code>README.md</code> file of the repository containing the custom generation strategy to see what the new arguments and output type differences are, if they exist. Otherwise, you can assume it works like the base <a href="/docs/transformers/pr_43265/en/main_classes/text_generation#transformers.GenerationMixin.generate">generate()</a> method.</p> <blockquote class="tip" data-svelte-h="svelte-1s1yceq"><p>You can find all custom generation methods by <a href="https://huggingface.co/models?other=custom_generate" rel="nofollow">searching for their custom tag.</a>, <code>custom_generate</code>.</p></blockquote> <p data-svelte-h="svelte-6fygoq">Consider the Hub repository <a href="https://huggingface.co/transformers-community/custom_generate_example" rel="nofollow">transformers-community/custom_generate_example</a> as an example. The <code>README.md</code> states that it has an additional input argument, <code>left_padding</code>, which adds a number of padding tokens before the prompt.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-py "><!-- HTML_TAG_START -->gen_out = model.generate( | |
| **inputs, custom_generate=<span class="hljs-string">"transformers-community/custom_generate_example"</span>, trust_remote_code=<span class="hljs-literal">True</span>, left_padding=<span class="hljs-number">5</span> | |
| ) | |
| <span class="hljs-built_in">print</span>(tokenizer.batch_decode(gen_out)[<span class="hljs-number">0</span>]) | |
| <span class="hljs-string">'<|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|>The quick brown fox jumps over the lazy dog.\n\nThe sentence "The quick'</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1twkewh">If the custom method has pinned Python requirements that your environment doesn’t meet, you’ll get an exception about missing requirements. For instance, <a href="https://huggingface.co/transformers-community/custom_generate_bad_requirements" rel="nofollow">transformers-community/custom_generate_bad_requirements</a> has an impossible set of requirements defined in its <code>custom_generate/requirements.txt</code> file, and you’ll see the error message below if you try to run it.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-text "><!-- HTML_TAG_START -->ImportError: Missing requirements in your local environment for `transformers-community/custom_generate_bad_requirements`: | |
| foo (installed: None) | |
| bar==0.0.0 (installed: None) | |
| torch>=99.0 (installed: 2.6.0)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-7d74dd">Updating your Python requirements accordingly will remove this error message.</p> <h3 class="relative group"><a id="creating-a-custom-generation-method" 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" href="#creating-a-custom-generation-method"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Creating a custom generation method</span></h3> <p data-svelte-h="svelte-1t2t779">To create a new generation method, you need to create a new <a href="https://huggingface.co/new" rel="nofollow"><strong>Model</strong></a> repository and push a few files into it.</p> <ol data-svelte-h="svelte-miimk7"><li>The model you’ve designed your generation method with.</li> <li><code>custom_generate/generate.py</code>, which contains all the logic for your custom generation method.</li> <li><code>custom_generate/requirements.txt</code>, used to optionally add new Python requirements and/or lock specific versions to correctly use your method.</li> <li><code>README.md</code>, where you should add the <code>custom_generate</code> tag and document any new arguments or output type differences of your custom method here.</li></ol> <p data-svelte-h="svelte-uqkppw">After you’ve added all required files, your repository should look like this</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-text "><!-- HTML_TAG_START -->your_repo/ | |
| ├── README.md # include the 'custom_generate' tag | |
| ├── config.json | |
| ├── ... | |
| └── custom_generate/ | |
| ├── generate.py | |
| └── requirements.txt<!-- HTML_TAG_END --></pre></div> <h4 class="relative group"><a id="adding-the-base-model" 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" href="#adding-the-base-model"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Adding the base model</span></h4> <p data-svelte-h="svelte-1k64pn0">The starting point for your custom generation method is a model repository just like any other. The model to add to this repository should be the model you’ve designed your method with, and it is meant to be part of a working self-contained model-generate pair. When the model in this repository is loaded, your custom generation method will override <code>generate</code>. Don’t worry — your generation method can still be loaded with any other Transformers model, as explained in the section above.</p> <p data-svelte-h="svelte-rqtax3">If you simply want to copy an existing model, you can do</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-py "><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoModelForCausalLM, AutoTokenizer | |
| tokenizer = AutoTokenizer.from_pretrained(<span class="hljs-string">"source/model_repo"</span>) | |
| model = AutoModelForCausalLM.from_pretrained(<span class="hljs-string">"source/model_repo"</span>) | |
| tokenizer.save_pretrained(<span class="hljs-string">"your/generation_method"</span>, push_to_hub=<span class="hljs-literal">True</span>) | |
| model.save_pretrained(<span class="hljs-string">"your/generation_method"</span>, push_to_hub=<span class="hljs-literal">True</span>)<!-- HTML_TAG_END --></pre></div> <h4 class="relative group"><a id="generatepy" 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" href="#generatepy"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>generate.py</span></h4> <p data-svelte-h="svelte-yomicr">This is the core of your generation method. It <em>must</em> contain a method named <code>generate</code>, and this method <em>must</em> contain a <code>model</code> argument as its first argument. <code>model</code> is the model instance, which means you have access to all attributes and methods in the model, including the ones defined in <a href="/docs/transformers/pr_43265/en/main_classes/text_generation#transformers.GenerationMixin">GenerationMixin</a> (like the base <code>generate</code> method).</p> <blockquote class="warning" data-svelte-h="svelte-1v9amjp"><p><code>generate.py</code> must be placed in a folder named <code>custom_generate</code>, and not at the root level of the repository. The file paths for this feature are hardcoded.</p></blockquote> <p data-svelte-h="svelte-1bt5w0f">Under the hood, when the base <a href="/docs/transformers/pr_43265/en/main_classes/text_generation#transformers.GenerationMixin.generate">generate()</a> method is called with a <code>custom_generate</code> argument, it first checks its Python requirements (if any), then locates the custom <code>generate</code> method in <code>generate.py</code>, and finally calls the custom <code>generate</code>. All received arguments and <code>model</code> are forwarded to your custom <code>generate</code> method, with the exception of the arguments used to trigger the custom generation (<code>trust_remote_code</code> and <code>custom_generate</code>).</p> <p data-svelte-h="svelte-1m56d80">This means your <code>generate</code> can have a mix of original and custom arguments (as well as a different output type) as shown below.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-py "><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">generate</span>(<span class="hljs-params">model, input_ids, generation_config=<span class="hljs-literal">None</span>, left_padding=<span class="hljs-literal">None</span>, **kwargs</span>): | |
| generation_config = generation_config <span class="hljs-keyword">or</span> model.generation_config <span class="hljs-comment"># default to the model generation config</span> | |
| cur_length = input_ids.shape[<span class="hljs-number">1</span>] | |
| max_length = generation_config.max_length <span class="hljs-keyword">or</span> cur_length + generation_config.max_new_tokens | |
| <span class="hljs-comment"># Example of custom argument: add `left_padding` (integer) pad tokens before the prompt</span> | |
| <span class="hljs-keyword">if</span> left_padding <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">None</span>: | |
| <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> <span class="hljs-built_in">isinstance</span>(left_padding, <span class="hljs-built_in">int</span>) <span class="hljs-keyword">or</span> left_padding < <span class="hljs-number">0</span>: | |
| <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">f"left_padding must be an integer larger than 0, but is <span class="hljs-subst">{left_padding}</span>"</span>) | |
| pad_token = kwargs.pop(<span class="hljs-string">"pad_token"</span>, <span class="hljs-literal">None</span>) <span class="hljs-keyword">or</span> generation_config.pad_token_id <span class="hljs-keyword">or</span> model.config.pad_token_id | |
| <span class="hljs-keyword">if</span> pad_token <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>: | |
| <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"pad_token is not defined"</span>) | |
| batch_size = input_ids.shape[<span class="hljs-number">0</span>] | |
| pad_tensor = torch.full(size=(batch_size, left_padding), fill_value=pad_token).to(input_ids.device) | |
| input_ids = torch.cat((pad_tensor, input_ids), dim=<span class="hljs-number">1</span>) | |
| cur_length = input_ids.shape[<span class="hljs-number">1</span>] | |
| <span class="hljs-comment"># Simple greedy decoding loop</span> | |
| <span class="hljs-keyword">while</span> cur_length < max_length: | |
| logits = model(input_ids).logits | |
| next_token_logits = logits[:, -<span class="hljs-number">1</span>, :] | |
| next_tokens = torch.argmax(next_token_logits, dim=-<span class="hljs-number">1</span>) | |
| input_ids = torch.cat((input_ids, next_tokens[:, <span class="hljs-literal">None</span>]), dim=-<span class="hljs-number">1</span>) | |
| cur_length += <span class="hljs-number">1</span> | |
| <span class="hljs-keyword">return</span> input_ids<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-vo2bry">Follow the recommended practices below to ensure your custom generation method works as expected.</p> <ul data-svelte-h="svelte-12hgjac"><li>Feel free to reuse the logic for validation and input preparation in the original <a href="/docs/transformers/pr_43265/en/main_classes/text_generation#transformers.GenerationMixin.generate">generate()</a>.</li> <li>Pin the <code>transformers</code> version in the requirements if you use any private method/attribute in <code>model</code>.</li> <li>Consider adding model validation, input validation, or even a separate test file to help users sanity-check your code in their environment.</li></ul> <p data-svelte-h="svelte-1gfwext">Your custom <code>generate</code> method can relative import code from the <code>custom_generate</code> folder. For example, if you have a <code>utils.py</code> file, you can import it like this:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-py "><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> .utils <span class="hljs-keyword">import</span> some_function<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1uzecn9">Only relative imports from the same-level <code>custom_generate</code> folder are supported. Parent/sibling folder imports are not valid. The <code>custom_generate</code> argument also works locally with any directory that contains a <code>custom_generate</code> structure, which is the recommended workflow for developing your custom generation method.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-py "><!-- HTML_TAG_START -->gen_out = model.generate(**inputs, custom_generate=<span class="hljs-string">"path/to/local/dir"</span>, trust_remote_code=<span class="hljs-literal">True</span>)<!-- HTML_TAG_END --></pre></div> <blockquote class="warning" data-svelte-h="svelte-1sdefpf"><p>Loading a local directory still executes its <code>custom_generate/generate.py</code>, so it requires <code>trust_remote_code=True</code> just like a Hub repository. Only pass <code>trust_remote_code=True</code> for code you’ve written or reviewed.</p></blockquote> <h4 class="relative group"><a id="requirementstxt" 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" href="#requirementstxt"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>requirements.txt</span></h4> <p data-svelte-h="svelte-i80d4s">You can optionally specify additional Python requirements in a <code>requirements.txt</code> file inside the <code>custom_generate</code> folder. These are checked at runtime and an exception will be thrown if they’re missing, nudging users to update their environment accordingly.</p> <h4 class="relative group"><a id="readmemd" 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" href="#readmemd"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>README.md</span></h4> <p data-svelte-h="svelte-gvnc7t">The root level <code>README.md</code> in the model repository usually describes the model therein. However, since the focus of the repository is the custom generation method, we highly recommend to shift its focus towards describing the custom generation method. In addition to a description of the method, we recommend documenting any input and/or output differences to the original <a href="/docs/transformers/pr_43265/en/main_classes/text_generation#transformers.GenerationMixin.generate">generate()</a>. This way, users can focus on what’s new, and rely on Transformers docs for generic implementation details.</p> <p data-svelte-h="svelte-1r2pptl">For discoverability, we highly recommend you to add the <code>custom_generate</code> tag to your repository. To do so, the top of your <code>README.md</code> file should look like the example below. After you push the file, you should see the tag in your repository!</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-text "><!-- HTML_TAG_START -->--- | |
| library_name: transformers | |
| tags: | |
| - custom_generate | |
| --- | |
| (your markdown content here)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-gw1adn">Recommended practices:</p> <ul data-svelte-h="svelte-1vihouh"><li>Document input and output differences in <a href="/docs/transformers/pr_43265/en/main_classes/text_generation#transformers.GenerationMixin.generate">generate()</a>.</li> <li>Add self-contained examples to enable quick experimentation.</li> <li>Describe soft-requirements such as if the method only works well with a certain family of models.</li></ul> <h3 class="relative group"><a id="reusing-generate-s-input-preparation" 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" href="#reusing-generate-s-input-preparation"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Reusing generate ’s input preparation</span></h3> <p data-svelte-h="svelte-10ug5bh">If you’re adding a new decoding loop, you might want to preserve the input preparation present in <code>generate</code> (batch expansion, attention masks, logits processors, stopping criteria, etc.). You can also pass a <strong>callable</strong> to <code>custom_generate</code> to reuse <a href="/docs/transformers/pr_43265/en/main_classes/text_generation#transformers.GenerationMixin.generate">generate()</a>’s full preparation pipeline while overriding only the decoding loop.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-py "><!-- HTML_TAG_START --><span class="hljs-keyword">def</span> <span class="hljs-title function_">custom_loop</span>(<span class="hljs-params">model, input_ids, attention_mask, logits_processor, stopping_criteria, generation_config, **model_kwargs</span>): | |
| next_tokens = input_ids | |
| <span class="hljs-keyword">while</span> input_ids.shape[<span class="hljs-number">1</span>] < stopping_criteria[<span class="hljs-number">0</span>].max_length: | |
| logits = model(next_tokens, attention_mask=attention_mask, **model_kwargs).logits | |
| next_token_logits = logits_processor(input_ids, logits[:, -<span class="hljs-number">1</span>, :]) | |
| next_tokens = torch.argmax(next_token_logits, dim=-<span class="hljs-number">1</span>)[:, <span class="hljs-literal">None</span>] | |
| input_ids = torch.cat((input_ids, next_tokens), dim=-<span class="hljs-number">1</span>) | |
| attention_mask = torch.cat((attention_mask, torch.ones_like(next_tokens)), dim=-<span class="hljs-number">1</span>) | |
| <span class="hljs-keyword">return</span> input_ids | |
| output = model.generate( | |
| **inputs, | |
| custom_generate=custom_loop, | |
| max_new_tokens=<span class="hljs-number">10</span>, | |
| )<!-- HTML_TAG_END --></pre></div> <blockquote class="tip" data-svelte-h="svelte-me3n47"><p>If you publish a <code>custom_generate</code> repository, your <code>generate</code> implementation can itself define a callable and pass it to <code>model.generate()</code>. This lets you customize the decoding loop while still benefiting from Transformers’ built-in input preparation logic.</p></blockquote> <h3 class="relative group"><a id="finding-custom-generation-methods" 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" href="#finding-custom-generation-methods"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Finding custom generation methods</span></h3> <p data-svelte-h="svelte-1oqs5iw">You can find all custom generation methods by <a href="https://huggingface.co/models?other=custom_generate" rel="nofollow">searching for their custom tag.</a>, <code>custom_generate</code>. In addition to the tag, we curate two collections of <code>custom_generate</code> methods:</p> <ul data-svelte-h="svelte-186mhwr"><li><a href="https://huggingface.co/collections/transformers-community/custom-generation-methods-community-6888fb1da0efbc592d3a8ab6" rel="nofollow">Custom generation methods - Community</a> — a collection of powerful methods contributed by the community;</li> <li><a href="https://huggingface.co/collections/transformers-community/custom-generation-methods-tutorials-6823589657a94940ea02cfec" rel="nofollow">Custom generation methods - Tutorials</a> — a collection of reference implementations for methods that previously were part of <code>transformers</code>, as well as tutorials for <code>custom_generate</code>.</li></ul> <h2 class="relative group"><a id="resources" 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" href="#resources"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Resources</span></h2> <p data-svelte-h="svelte-7psx0p">Read the <a href="https://huggingface.co/blog/how-to-generate" rel="nofollow">How to generate text: using different decoding methods for language generation with Transformers</a> blog post for an explanation of how common decoding strategies work.</p> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/transformers/blob/main/docs/source/en/generation_strategies.md" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg> <span data-svelte-h="svelte-zjs2n5"><span class="underline">Update</span> on GitHub</span></a> <p></p> | |
| <script> | |
| { | |
| __sveltekit_1gaarxw = { | |
| assets: "/docs/transformers/pr_43265/en", | |
| base: "/docs/transformers/pr_43265/en", | |
| env: {} | |
| }; | |
| const element = document.currentScript.parentElement; | |
| const data = [null,null]; | |
| Promise.all([ | |
| import("/docs/transformers/pr_43265/en/_app/immutable/entry/start.1dae3980.js"), | |
| import("/docs/transformers/pr_43265/en/_app/immutable/entry/app.66dba7a3.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 53], | |
| data, | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 69.2 kB
- Xet hash:
- b8523b88748409d359dee8107711c3f5c3339ff20d6d5b69348d7a02a916e323
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.