Buckets:

rtrm's picture
download
raw
17.5 kB
import{s as fe,o as Ue,n as Te}from"../chunks/scheduler.18a86fab.js";import{S as Je,i as be,g as i,s as n,r as X,A as we,h as r,f as a,c as l,j as de,u as v,x as p,k as ye,y as je,a as s,v as W,d as G,t as I,w as R}from"../chunks/index.98837b22.js";import{T as _e}from"../chunks/Tip.77304350.js";import{C as Me}from"../chunks/CodeBlock.8d0c2e8a.js";import{H as ae}from"../chunks/Heading.7e7e0c5b.js";import{E as Ce}from"../chunks/index.499f366c.js";function ke(x){let o,m="Caching should only be used for <strong>inference</strong>. It may cause unexpected errors if it’s enabled during training.";return{c(){o=i("p"),o.innerHTML=m},l(c){o=r(c,"P",{"data-svelte-h":!0}),p(o)!=="svelte-16dnkl8"&&(o.innerHTML=m)},m(c,B){s(c,o,B)},p:Te,d(c){c&&a(o)}}}function Ze(x){let o,m,c,B,u,N,d,se="Imagine you’re having a conversation with someone, and instead of remembering what they previously said, they have to start from scratch every time you respond. This would be slow and inefficient, right?",V,y,ne="You can extend this analogy to transformer models. Autoregressive model generation can be slow because it makes a prediction one token at a time. Each new prediction is dependent on all the previous context.",Q,M,le="To predict the 1000th token, the model requires information from the previous 999 tokens. The information is represented as matrix multiplications across the token representations.",F,f,oe="To predict the 1001th token, you need the same information from the previous 999 tokens in addition to any information from the 1000th token. This is a lot of matrix multiplications a model has to compute over and over for each token!",H,U,ie="A key-value (KV) cache eliminates this inefficiency by storing kv pairs derived from the attention layers of previously processed tokens. The stored kv pairs are retrieved from the cache and reused for subsequent tokens, avoiding the need to recompute.",$,h,z,T,E,J,re='When you use Transformers’ <a href="/docs/transformers/pr_33962/en/internal/generation_utils#transformers.Cache">Cache</a> class, the self-attention module performs several critical steps to integrate past and present information.',S,b,ce='<li><p>The attention module concatenates current kv pairs with past kv pairs stored in the cache. This creates attentions weights with the shape <code>(new_tokens_length, past_kv_length + new_tokens_length)</code>. The current and past kv pairs are essentially combined to compute the attention scores, ensuring a model is aware of previous context and the current input.</p></li> <li><p>When the <code>forward</code> method is called iteratively, it’s crucial that the attention mask shape matches the combined length of the past and current kv pairs. The attention mask should have the shape <code>(batch_size, past_kv_length + new_tokens_length)</code>. This is typically handled internally in <a href="/docs/transformers/pr_33962/en/main_classes/text_generation#transformers.GenerationMixin.generate">generate()</a>, but if you want to implement your own generation loop with <a href="/docs/transformers/pr_33962/en/internal/generation_utils#transformers.Cache">Cache</a>, keep this in mind! The attention mask should hold the past and current token values.</p></li> <li><p>It is also important to be aware of the <code>cache_position</code>. This is important if you want to reuse a prefilled <a href="/docs/transformers/pr_33962/en/internal/generation_utils#transformers.Cache">Cache</a> with the <code>forward</code> method because you have to pass a valid <code>cache_position</code> value. This indicates the input positions in a sequence. <code>cache_position</code> is unaffected by padding, and it always adds one more position for each token. For example, if a kv cache contains 10 tokens - regardless of pad tokens - the cache position for the next token should be <code>torch.tensor([10])</code>.</p></li>',q,w,pe='The example below demonstrates how to create a generation loop with <a href="/docs/transformers/pr_33962/en/internal/generation_utils#transformers.DynamicCache">DynamicCache</a>. As discussed, the attention mask is a concatenation of past and current token values and <code>1</code> is added to the cache position for the next token.',L,j,A,_,D,C,he='Before the <a href="/docs/transformers/pr_33962/en/internal/generation_utils#transformers.Cache">Cache</a> class, the cache used to be stored as a tuple of tuples of tensors. This format has is dynamic because it grows as text is generated, similar to <a href="/docs/transformers/pr_33962/en/internal/generation_utils#transformers.DynamicCache">DynamicCache</a>.',K,k,me='If your project depends on this legacy format, you can convert between <a href="/docs/transformers/pr_33962/en/internal/generation_utils#transformers.DynamicCache">DynamicCache</a> and a tuple of tuples as shown below with the <a href="/docs/transformers/pr_33962/en/internal/generation_utils#transformers.DynamicCache.from_legacy_cache">from_legacy_cache()</a> and <a href="/docs/transformers/pr_33962/en/internal/generation_utils#transformers.DynamicCache.to_legacy_cache">DynamicCache.to_legacy_cache()</a> functions. This is helpful if you have custom logic for manipulating a cache in a specific format.',P,Z,O,g,ee,Y,te;return u=new ae({props:{title:"Caching",local:"caching",headingTag:"h1"}}),h=new _e({props:{warning:!0,$$slots:{default:[ke]},$$scope:{ctx:x}}}),T=new ae({props:{title:"Cache class",local:"cache-class",headingTag:"h2"}}),j=new Me({props:{code:"aW1wb3J0JTIwdG9yY2glMEFmcm9tJTIwdHJhbnNmb3JtZXJzJTIwaW1wb3J0JTIwQXV0b1Rva2VuaXplciUyQyUyMEF1dG9Nb2RlbEZvckNhdXNhbExNJTJDJTIwRHluYW1pY0NhY2hlJTBBJTBBbW9kZWxfaWQlMjAlM0QlMjAlMjJtZXRhLWxsYW1hJTJGTGxhbWEtMi03Yi1jaGF0LWhmJTIyJTBBbW9kZWwlMjAlM0QlMjBBdXRvTW9kZWxGb3JDYXVzYWxMTS5mcm9tX3ByZXRyYWluZWQobW9kZWxfaWQlMkMlMjB0b3JjaF9kdHlwZSUzRHRvcmNoLmJmbG9hdDE2JTJDJTIwZGV2aWNlX21hcCUzRCUyMmN1ZGElM0EwJTIyKSUwQXRva2VuaXplciUyMCUzRCUyMEF1dG9Ub2tlbml6ZXIuZnJvbV9wcmV0cmFpbmVkKG1vZGVsX2lkKSUwQSUwQXBhc3Rfa2V5X3ZhbHVlcyUyMCUzRCUyMER5bmFtaWNDYWNoZSgpJTBBbWVzc2FnZXMlMjAlM0QlMjAlNUIlN0IlMjJyb2xlJTIyJTNBJTIwJTIydXNlciUyMiUyQyUyMCUyMmNvbnRlbnQlMjIlM0ElMjAlMjJIZWxsbyUyQyUyMHdoYXQncyUyMHlvdXIlMjBuYW1lLiUyMiU3RCU1RCUwQWlucHV0cyUyMCUzRCUyMHRva2VuaXplci5hcHBseV9jaGF0X3RlbXBsYXRlKG1lc3NhZ2VzJTJDJTIwYWRkX2dlbmVyYXRpb25fcHJvbXB0JTNEVHJ1ZSUyQyUyMHJldHVybl90ZW5zb3JzJTNEJTIycHQlMjIlMkMlMjByZXR1cm5fZGljdCUzRFRydWUpLnRvKCUyMmN1ZGElM0EwJTIyKSUwQSUwQWdlbmVyYXRlZF9pZHMlMjAlM0QlMjBpbnB1dHMuaW5wdXRfaWRzJTBBY2FjaGVfcG9zaXRpb24lMjAlM0QlMjB0b3JjaC5hcmFuZ2UoaW5wdXRzLmlucHV0X2lkcy5zaGFwZSU1QjElNUQlMkMlMjBkdHlwZSUzRHRvcmNoLmludDY0JTJDJTIwZGV2aWNlJTNEJTIyY3VkYSUzQTAlMjIpJTBBbWF4X25ld190b2tlbnMlMjAlM0QlMjAxMCUwQSUwQWZvciUyMF8lMjBpbiUyMHJhbmdlKG1heF9uZXdfdG9rZW5zKSUzQSUwQSUyMCUyMCUyMCUyMG91dHB1dHMlMjAlM0QlMjBtb2RlbCgqKmlucHV0cyUyQyUyMGNhY2hlX3Bvc2l0aW9uJTNEY2FjaGVfcG9zaXRpb24lMkMlMjBwYXN0X2tleV92YWx1ZXMlM0RwYXN0X2tleV92YWx1ZXMlMkMlMjB1c2VfY2FjaGUlM0RUcnVlKSUwQSUyMCUyMCUyMCUyMCUyMyUyMEdyZWVkaWx5JTIwc2FtcGxlJTIwb25lJTIwbmV4dCUyMHRva2VuJTBBJTIwJTIwJTIwJTIwbmV4dF90b2tlbl9pZHMlMjAlM0QlMjBvdXRwdXRzLmxvZ2l0cyU1QiUzQSUyQyUyMC0xJTNBJTVELmFyZ21heCgtMSklMEElMjAlMjAlMjAlMjBnZW5lcmF0ZWRfaWRzJTIwJTNEJTIwdG9yY2guY2F0KCU1QmdlbmVyYXRlZF9pZHMlMkMlMjBuZXh0X3Rva2VuX2lkcyU1RCUyQyUyMGRpbSUzRC0xKSUwQSUyMCUyMCUyMCUyMCUyMyUyMFByZXBhcmUlMjBpbnB1dHMlMjBmb3IlMjB0aGUlMjBuZXh0JTIwZ2VuZXJhdGlvbiUyMHN0ZXAlMjBieSUyMGxlYXZpbmclMjB1bnByb2Nlc3NlZCUyMHRva2VucyUyQyUyMGluJTIwb3VyJTIwY2FzZSUyMHdlJTIwaGF2ZSUyMG9ubHklMjBvbmUlMjBuZXclMjB0b2tlbiUwQSUyMCUyMCUyMCUyMCUyMyUyMGFuZCUyMGV4cGFuZGluZyUyMGF0dG4lMjBtYXNrJTIwZm9yJTIwdGhlJTIwbmV3JTIwdG9rZW4lMkMlMjBhcyUyMGV4cGxhaW5lZCUyMGFib3ZlJTBBJTIwJTIwJTIwJTIwYXR0ZW50aW9uX21hc2slMjAlM0QlMjBpbnB1dHMlNUIlMjJhdHRlbnRpb25fbWFzayUyMiU1RCUwQSUyMCUyMCUyMCUyMGF0dGVudGlvbl9tYXNrJTIwJTNEJTIwdG9yY2guY2F0KCU1QmF0dGVudGlvbl9tYXNrJTJDJTIwYXR0ZW50aW9uX21hc2submV3X29uZXMoKGF0dGVudGlvbl9tYXNrLnNoYXBlJTVCMCU1RCUyQyUyMDEpKSU1RCUyQyUyMGRpbSUzRC0xKSUwQSUyMCUyMCUyMCUyMGlucHV0cyUyMCUzRCUyMCU3QiUyMmlucHV0X2lkcyUyMiUzQSUyMG5leHRfdG9rZW5faWRzJTJDJTIwJTIyYXR0ZW50aW9uX21hc2slMjIlM0ElMjBhdHRlbnRpb25fbWFzayU3RCUwQSUyMCUyMCUyMCUyMGNhY2hlX3Bvc2l0aW9uJTIwJTNEJTIwY2FjaGVfcG9zaXRpb24lNUItMSUzQSU1RCUyMCUyQiUyMDElMjAlMjMlMjBhZGQlMjBvbmUlMjBtb3JlJTIwcG9zaXRpb24lMjBmb3IlMjB0aGUlMjBuZXh0JTIwdG9rZW4lMEElMEFwcmludCh0b2tlbml6ZXIuYmF0Y2hfZGVjb2RlKGdlbmVyYXRlZF9pZHMlMkMlMjBza2lwX3NwZWNpYWxfdG9rZW5zJTNEVHJ1ZSklNUIwJTVEKSUwQSUyMiU1QklOU1QlNUQlMjBIZWxsbyUyQyUyMHdoYXQncyUyMHlvdXIlMjBuYW1lLiUyMCU1QiUyRklOU1QlNUQlMjAlMjBIZWxsbyElMjBNeSUyMG5hbWUlMjBpcyUyMExMYU1BJTJDJTIy",highlighted:`<span class="hljs-keyword">import</span> torch
<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoTokenizer, AutoModelForCausalLM, DynamicCache
model_id = <span class="hljs-string">&quot;meta-llama/Llama-2-7b-chat-hf&quot;</span>
model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.bfloat16, device_map=<span class="hljs-string">&quot;cuda:0&quot;</span>)
tokenizer = AutoTokenizer.from_pretrained(model_id)
past_key_values = DynamicCache()
messages = [{<span class="hljs-string">&quot;role&quot;</span>: <span class="hljs-string">&quot;user&quot;</span>, <span class="hljs-string">&quot;content&quot;</span>: <span class="hljs-string">&quot;Hello, what&#x27;s your name.&quot;</span>}]
inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=<span class="hljs-literal">True</span>, return_tensors=<span class="hljs-string">&quot;pt&quot;</span>, return_dict=<span class="hljs-literal">True</span>).to(<span class="hljs-string">&quot;cuda:0&quot;</span>)
generated_ids = inputs.input_ids
cache_position = torch.arange(inputs.input_ids.shape[<span class="hljs-number">1</span>], dtype=torch.int64, device=<span class="hljs-string">&quot;cuda:0&quot;</span>)
max_new_tokens = <span class="hljs-number">10</span>
<span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(max_new_tokens):
outputs = model(**inputs, cache_position=cache_position, past_key_values=past_key_values, use_cache=<span class="hljs-literal">True</span>)
<span class="hljs-comment"># Greedily sample one next token</span>
next_token_ids = outputs.logits[:, -<span class="hljs-number">1</span>:].argmax(-<span class="hljs-number">1</span>)
generated_ids = torch.cat([generated_ids, next_token_ids], dim=-<span class="hljs-number">1</span>)
<span class="hljs-comment"># Prepare inputs for the next generation step by leaving unprocessed tokens, in our case we have only one new token</span>
<span class="hljs-comment"># and expanding attn mask for the new token, as explained above</span>
attention_mask = inputs[<span class="hljs-string">&quot;attention_mask&quot;</span>]
attention_mask = torch.cat([attention_mask, attention_mask.new_ones((attention_mask.shape[<span class="hljs-number">0</span>], <span class="hljs-number">1</span>))], dim=-<span class="hljs-number">1</span>)
inputs = {<span class="hljs-string">&quot;input_ids&quot;</span>: next_token_ids, <span class="hljs-string">&quot;attention_mask&quot;</span>: attention_mask}
cache_position = cache_position[-<span class="hljs-number">1</span>:] + <span class="hljs-number">1</span> <span class="hljs-comment"># add one more position for the next token</span>
<span class="hljs-built_in">print</span>(tokenizer.batch_decode(generated_ids, skip_special_tokens=<span class="hljs-literal">True</span>)[<span class="hljs-number">0</span>])
<span class="hljs-string">&quot;[INST] Hello, what&#x27;s your name. [/INST] Hello! My name is LLaMA,&quot;</span>`,wrap:!1}}),_=new ae({props:{title:"Legacy cache format",local:"legacy-cache-format",headingTag:"h2"}}),Z=new Me({props:{code:"aW1wb3J0JTIwdG9yY2glMEFmcm9tJTIwdHJhbnNmb3JtZXJzJTIwaW1wb3J0JTIwQXV0b1Rva2VuaXplciUyQyUyMEF1dG9Nb2RlbEZvckNhdXNhbExNJTJDJTIwRHluYW1pY0NhY2hlJTBBJTBBdG9rZW5pemVyJTIwJTNEJTIwQXV0b1Rva2VuaXplci5mcm9tX3ByZXRyYWluZWQoJTIybWV0YS1sbGFtYSUyRkxsYW1hLTItN2ItY2hhdC1oZiUyMiklMEFtb2RlbCUyMCUzRCUyMEF1dG9Nb2RlbEZvckNhdXNhbExNLmZyb21fcHJldHJhaW5lZCglMjJtZXRhLWxsYW1hJTJGTGxhbWEtMi03Yi1jaGF0LWhmJTIyJTJDJTIwdG9yY2hfZHR5cGUlM0R0b3JjaC5mbG9hdDE2JTJDJTIwZGV2aWNlX21hcCUzRCUyMmF1dG8lMjIpJTBBaW5wdXRzJTIwJTNEJTIwdG9rZW5pemVyKCUyMkhlbGxvJTJDJTIwbXklMjBuYW1lJTIwaXMlMjIlMkMlMjByZXR1cm5fdGVuc29ycyUzRCUyMnB0JTIyKS50byhtb2RlbC5kZXZpY2UpJTBBJTBBJTIzJTIwJTYwcmV0dXJuX2RpY3RfaW5fZ2VuZXJhdGUlM0RUcnVlJTYwJTIwaXMlMjByZXF1aXJlZCUyMHRvJTIwcmV0dXJuJTIwdGhlJTIwY2FjaGUlMjBhbmQlMjAlNjByZXR1cm5fbGVnYWN5X2NhY2hlJTYwJTIwZm9yY2VzJTIwdGhlJTIwcmV0dXJuZWQlMjBjYWNoZSUwQSUyMyUyMGluJTIwdGhlJTIwbGVnYWN5JTIwZm9ybWF0JTBBZ2VuZXJhdGlvbl9vdXRwdXRzJTIwJTNEJTIwbW9kZWwuZ2VuZXJhdGUoKippbnB1dHMlMkMlMjByZXR1cm5fZGljdF9pbl9nZW5lcmF0ZSUzRFRydWUlMkMlMjByZXR1cm5fbGVnYWN5X2NhY2hlJTNEVHJ1ZSUyQyUyMG1heF9uZXdfdG9rZW5zJTNENSklMEElMEFjYWNoZSUyMCUzRCUyMER5bmFtaWNDYWNoZS5mcm9tX2xlZ2FjeV9jYWNoZShnZW5lcmF0aW9uX291dHB1dHMucGFzdF9rZXlfdmFsdWVzKSUwQWxlZ2FjeV9mb3JtYXRfY2FjaGUlMjAlM0QlMjBjYWNoZS50b19sZWdhY3lfY2FjaGUoKQ==",highlighted:`<span class="hljs-keyword">import</span> torch
<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoTokenizer, AutoModelForCausalLM, DynamicCache
tokenizer = AutoTokenizer.from_pretrained(<span class="hljs-string">&quot;meta-llama/Llama-2-7b-chat-hf&quot;</span>)
model = AutoModelForCausalLM.from_pretrained(<span class="hljs-string">&quot;meta-llama/Llama-2-7b-chat-hf&quot;</span>, torch_dtype=torch.float16, device_map=<span class="hljs-string">&quot;auto&quot;</span>)
inputs = tokenizer(<span class="hljs-string">&quot;Hello, my name is&quot;</span>, return_tensors=<span class="hljs-string">&quot;pt&quot;</span>).to(model.device)
<span class="hljs-comment"># \`return_dict_in_generate=True\` is required to return the cache and \`return_legacy_cache\` forces the returned cache</span>
<span class="hljs-comment"># in the legacy format</span>
generation_outputs = model.generate(**inputs, return_dict_in_generate=<span class="hljs-literal">True</span>, return_legacy_cache=<span class="hljs-literal">True</span>, max_new_tokens=<span class="hljs-number">5</span>)
cache = DynamicCache.from_legacy_cache(generation_outputs.past_key_values)
legacy_format_cache = cache.to_legacy_cache()`,wrap:!1}}),g=new Ce({props:{source:"https://github.com/huggingface/transformers/blob/main/docs/source/en/cache_explanation.md"}}),{c(){o=i("meta"),m=n(),c=i("p"),B=n(),X(u.$$.fragment),N=n(),d=i("p"),d.textContent=se,V=n(),y=i("p"),y.textContent=ne,Q=n(),M=i("p"),M.textContent=le,F=n(),f=i("p"),f.textContent=oe,H=n(),U=i("p"),U.textContent=ie,$=n(),X(h.$$.fragment),z=n(),X(T.$$.fragment),E=n(),J=i("p"),J.innerHTML=re,S=n(),b=i("ol"),b.innerHTML=ce,q=n(),w=i("p"),w.innerHTML=pe,L=n(),X(j.$$.fragment),A=n(),X(_.$$.fragment),D=n(),C=i("p"),C.innerHTML=he,K=n(),k=i("p"),k.innerHTML=me,P=n(),X(Z.$$.fragment),O=n(),X(g.$$.fragment),ee=n(),Y=i("p"),this.h()},l(e){const t=we("svelte-u9bgzb",document.head);o=r(t,"META",{name:!0,content:!0}),t.forEach(a),m=l(e),c=r(e,"P",{}),de(c).forEach(a),B=l(e),v(u.$$.fragment,e),N=l(e),d=r(e,"P",{"data-svelte-h":!0}),p(d)!=="svelte-1vgfrh0"&&(d.textContent=se),V=l(e),y=r(e,"P",{"data-svelte-h":!0}),p(y)!=="svelte-110unin"&&(y.textContent=ne),Q=l(e),M=r(e,"P",{"data-svelte-h":!0}),p(M)!=="svelte-1sc0ng3"&&(M.textContent=le),F=l(e),f=r(e,"P",{"data-svelte-h":!0}),p(f)!=="svelte-stwnf4"&&(f.textContent=oe),H=l(e),U=r(e,"P",{"data-svelte-h":!0}),p(U)!=="svelte-k1lwaa"&&(U.textContent=ie),$=l(e),v(h.$$.fragment,e),z=l(e),v(T.$$.fragment,e),E=l(e),J=r(e,"P",{"data-svelte-h":!0}),p(J)!=="svelte-115nr6k"&&(J.innerHTML=re),S=l(e),b=r(e,"OL",{"data-svelte-h":!0}),p(b)!=="svelte-13ua56p"&&(b.innerHTML=ce),q=l(e),w=r(e,"P",{"data-svelte-h":!0}),p(w)!=="svelte-1e00u5z"&&(w.innerHTML=pe),L=l(e),v(j.$$.fragment,e),A=l(e),v(_.$$.fragment,e),D=l(e),C=r(e,"P",{"data-svelte-h":!0}),p(C)!=="svelte-zsyl1w"&&(C.innerHTML=he),K=l(e),k=r(e,"P",{"data-svelte-h":!0}),p(k)!=="svelte-1disuer"&&(k.innerHTML=me),P=l(e),v(Z.$$.fragment,e),O=l(e),v(g.$$.fragment,e),ee=l(e),Y=r(e,"P",{}),de(Y).forEach(a),this.h()},h(){ye(o,"name","hf:doc:metadata"),ye(o,"content",ge)},m(e,t){je(document.head,o),s(e,m,t),s(e,c,t),s(e,B,t),W(u,e,t),s(e,N,t),s(e,d,t),s(e,V,t),s(e,y,t),s(e,Q,t),s(e,M,t),s(e,F,t),s(e,f,t),s(e,H,t),s(e,U,t),s(e,$,t),W(h,e,t),s(e,z,t),W(T,e,t),s(e,E,t),s(e,J,t),s(e,S,t),s(e,b,t),s(e,q,t),s(e,w,t),s(e,L,t),W(j,e,t),s(e,A,t),W(_,e,t),s(e,D,t),s(e,C,t),s(e,K,t),s(e,k,t),s(e,P,t),W(Z,e,t),s(e,O,t),W(g,e,t),s(e,ee,t),s(e,Y,t),te=!0},p(e,[t]){const ue={};t&2&&(ue.$$scope={dirty:t,ctx:e}),h.$set(ue)},i(e){te||(G(u.$$.fragment,e),G(h.$$.fragment,e),G(T.$$.fragment,e),G(j.$$.fragment,e),G(_.$$.fragment,e),G(Z.$$.fragment,e),G(g.$$.fragment,e),te=!0)},o(e){I(u.$$.fragment,e),I(h.$$.fragment,e),I(T.$$.fragment,e),I(j.$$.fragment,e),I(_.$$.fragment,e),I(Z.$$.fragment,e),I(g.$$.fragment,e),te=!1},d(e){e&&(a(m),a(c),a(B),a(N),a(d),a(V),a(y),a(Q),a(M),a(F),a(f),a(H),a(U),a($),a(z),a(E),a(J),a(S),a(b),a(q),a(w),a(L),a(A),a(D),a(C),a(K),a(k),a(P),a(O),a(ee),a(Y)),a(o),R(u,e),R(h,e),R(T,e),R(j,e),R(_,e),R(Z,e),R(g,e)}}}const ge='{"title":"Caching","local":"caching","sections":[{"title":"Cache class","local":"cache-class","sections":[],"depth":2},{"title":"Legacy cache format","local":"legacy-cache-format","sections":[],"depth":2}],"depth":1}';function Xe(x){return Ue(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class Ye extends Je{constructor(o){super(),be(this,o,Xe,Ze,fe,{})}}export{Ye as component};

Xet Storage Details

Size:
17.5 kB
·
Xet hash:
9513a054c6b556d96776eebedb3583259ec83a1bda1cc10e9df5134eba6df80c

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.