Buckets:

rtrm's picture
download
raw
15.9 kB
import{s as ve,o as Ze,n as Ce}from"../chunks/scheduler.182ea377.js";import{S as Ne,i as Re,g as i,s as n,p as f,A as Be,h as o,f as s,c as a,j as F,q as M,m as c,k as d,v as T,a as l,r as y,d as J,t as h,u as U}from"../chunks/index.008d68e4.js";import{T as Se}from"../chunks/Tip.4f096367.js";import{I as Ee}from"../chunks/IconCopyLink.96bbb92b.js";import{C as q}from"../chunks/CodeBlock.5ed6eb7b.js";import{D as Qe}from"../chunks/DocNotebookDropdown.bb388256.js";function ke(H){let p,j='Read this <a href="https://huggingface.co/blog/sd_distillation" rel="nofollow">blog post</a> to learn more about how knowledge distillation training works to produce a faster, smaller, and cheaper generative model.';return{c(){p=i("p"),p.innerHTML=j},l(r){p=o(r,"P",{"data-svelte-h":!0}),c(p)!=="svelte-gx7uq8"&&(p.innerHTML=j)},m(r,u){l(r,p,u)},p:Ce,d(r){r&&s(p)}}}function We(H){let p,j,r,u,X,_,ue,x,fe="Distilled Stable Diffusion inference",Y,V,D,E,Me='Stable Diffusion inference can be a computationally intensive process because it must iteratively denoise the latents to generate an image. To reduce the computational burden, you can use a <em>distilled</em> version of the Stable Diffusion model from <a href="https://huggingface.co/nota-ai" rel="nofollow">Nota AI</a>. The distilled version of their Stable Diffusion model eliminates some of the residual and attention blocks from the UNet, reducing the model size by 51% and improving latency on CPU/GPU by 43%.',z,w,L,v,Te="Let’s load the distilled Stable Diffusion model and compare it against the original Stable Diffusion model:",K,Z,O,C,ye="Given a prompt, get the inference time for the original model:",ee,N,te,R,Je="Time the distilled model inference:",se,B,le,b,he='<div><img class="rounded-xl" src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/original_sd.png"/> <figcaption class="mt-2 text-center text-sm text-gray-500">original Stable Diffusion (45781.5 ms)</figcaption></div> <div><img class="rounded-xl" src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/distilled_sd.png"/> <figcaption class="mt-2 text-center text-sm text-gray-500">distilled Stable Diffusion (29884.2 ms)</figcaption></div>',ne,m,g,P,S,me,A,Ue="Tiny AutoEncoder",ae,Q,we='To speed inference up even more, use a tiny distilled version of the <a href="https://huggingface.co/sayakpaul/taesdxl-diffusers" rel="nofollow">Stable Diffusion VAE</a> to denoise the latents into images. Replace the VAE in the distilled Stable Diffusion model with the tiny VAE:',ie,k,oe,W,be="Time the distilled model and distilled VAE inference:",pe,$,re,I,ge='<div><img class="rounded-xl" src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/distilled_sd_vae.png"/> <figcaption class="mt-2 text-center text-sm text-gray-500">distilled Stable Diffusion + Tiny AutoEncoder (27165.7 ms)</figcaption></div>',de;return _=new Ee({}),V=new Qe({props:{classNames:"absolute z-10 right-0 top-0",options:[{label:"Mixed",value:"https://colab.research.google.com/github/huggingface/notebooks/blob/main/diffusers_doc/ko/distilled_sd.ipynb"},{label:"PyTorch",value:"https://colab.research.google.com/github/huggingface/notebooks/blob/main/diffusers_doc/ko/pytorch/distilled_sd.ipynb"},{label:"TensorFlow",value:"https://colab.research.google.com/github/huggingface/notebooks/blob/main/diffusers_doc/ko/tensorflow/distilled_sd.ipynb"},{label:"Mixed",value:"https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/diffusers_doc/ko/distilled_sd.ipynb"},{label:"PyTorch",value:"https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/diffusers_doc/ko/pytorch/distilled_sd.ipynb"},{label:"TensorFlow",value:"https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/diffusers_doc/ko/tensorflow/distilled_sd.ipynb"}]}}),w=new Se({props:{$$slots:{default:[ke]},$$scope:{ctx:H}}}),Z=new q({props:{code:"ZnJvbSUyMGRpZmZ1c2VycyUyMGltcG9ydCUyMFN0YWJsZURpZmZ1c2lvblBpcGVsaW5lJTBBaW1wb3J0JTIwdG9yY2glMEElMEFkaXN0aWxsZWQlMjAlM0QlMjBTdGFibGVEaWZmdXNpb25QaXBlbGluZS5mcm9tX3ByZXRyYWluZWQoJTBBJTIwJTIwJTIwJTIwJTIybm90YS1haSUyRmJrLXNkbS1zbWFsbCUyMiUyQyUyMHRvcmNoX2R0eXBlJTNEdG9yY2guZmxvYXQxNiUyQyUyMHVzZV9zYWZldGVuc29ycyUzRFRydWUlMkMlMEEpLnRvKCUyMmN1ZGElMjIpJTBBJTBBb3JpZ2luYWwlMjAlM0QlMjBTdGFibGVEaWZmdXNpb25QaXBlbGluZS5mcm9tX3ByZXRyYWluZWQoJTBBJTIwJTIwJTIwJTIwJTIyQ29tcFZpcyUyRnN0YWJsZS1kaWZmdXNpb24tdjEtNCUyMiUyQyUyMHRvcmNoX2R0eXBlJTNEdG9yY2guZmxvYXQxNiUyQyUyMHVzZV9zYWZldGVuc29ycyUzRFRydWUlMkMlMEEpLnRvKCUyMmN1ZGElMjIp",highlighted:`<span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> StableDiffusionPipeline
<span class="hljs-keyword">import</span> torch
distilled = StableDiffusionPipeline.from_pretrained(
<span class="hljs-string">&quot;nota-ai/bk-sdm-small&quot;</span>, torch_dtype=torch.float16, use_safetensors=<span class="hljs-literal">True</span>,
).to(<span class="hljs-string">&quot;cuda&quot;</span>)
original = StableDiffusionPipeline.from_pretrained(
<span class="hljs-string">&quot;CompVis/stable-diffusion-v1-4&quot;</span>, torch_dtype=torch.float16, use_safetensors=<span class="hljs-literal">True</span>,
).to(<span class="hljs-string">&quot;cuda&quot;</span>)`}}),N=new q({props:{code:"aW1wb3J0JTIwdGltZSUwQSUwQXNlZWQlMjAlM0QlMjAyMDIzJTBBZ2VuZXJhdG9yJTIwJTNEJTIwdG9yY2gubWFudWFsX3NlZWQoc2VlZCklMEElMEFOVU1fSVRFUlNfVE9fUlVOJTIwJTNEJTIwMyUwQU5VTV9JTkZFUkVOQ0VfU1RFUFMlMjAlM0QlMjAyNSUwQU5VTV9JTUFHRVNfUEVSX1BST01QVCUyMCUzRCUyMDQlMEElMEFwcm9tcHQlMjAlM0QlMjAlMjJhJTIwZ29sZGVuJTIwdmFzZSUyMHdpdGglMjBkaWZmZXJlbnQlMjBmbG93ZXJzJTIyJTBBJTBBc3RhcnQlMjAlM0QlMjB0aW1lLnRpbWVfbnMoKSUwQWZvciUyMF8lMjBpbiUyMHJhbmdlKE5VTV9JVEVSU19UT19SVU4pJTNBJTBBJTIwJTIwJTIwJTIwaW1hZ2VzJTIwJTNEJTIwb3JpZ2luYWwoJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcHJvbXB0JTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwbnVtX2luZmVyZW5jZV9zdGVwcyUzRE5VTV9JTkZFUkVOQ0VfU1RFUFMlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBnZW5lcmF0b3IlM0RnZW5lcmF0b3IlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBudW1faW1hZ2VzX3Blcl9wcm9tcHQlM0ROVU1fSU1BR0VTX1BFUl9QUk9NUFQlMEElMjAlMjAlMjAlMjApLmltYWdlcyUwQWVuZCUyMCUzRCUyMHRpbWUudGltZV9ucygpJTBBb3JpZ2luYWxfc2QlMjAlM0QlMjBmJTIyJTdCKGVuZCUyMC0lMjBzdGFydCklMjAlMkYlMjAxZTYlM0EuMWYlN0QlMjIlMEElMEFwcmludChmJTIyRXhlY3V0aW9uJTIwdGltZSUyMC0tJTIwJTdCb3JpZ2luYWxfc2QlN0QlMjBtcyU1Q24lMjIpJTBBJTIyRXhlY3V0aW9uJTIwdGltZSUyMC0tJTIwNDU3ODEuNSUyMG1zJTIy",highlighted:`<span class="hljs-keyword">import</span> time
seed = <span class="hljs-number">2023</span>
generator = torch.manual_seed(seed)
NUM_ITERS_TO_RUN = <span class="hljs-number">3</span>
NUM_INFERENCE_STEPS = <span class="hljs-number">25</span>
NUM_IMAGES_PER_PROMPT = <span class="hljs-number">4</span>
prompt = <span class="hljs-string">&quot;a golden vase with different flowers&quot;</span>
start = time.time_ns()
<span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(NUM_ITERS_TO_RUN):
images = original(
prompt,
num_inference_steps=NUM_INFERENCE_STEPS,
generator=generator,
num_images_per_prompt=NUM_IMAGES_PER_PROMPT
).images
end = time.time_ns()
original_sd = <span class="hljs-string">f&quot;<span class="hljs-subst">{(end - start) / <span class="hljs-number">1e6</span>:<span class="hljs-number">.1</span>f}</span>&quot;</span>
<span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Execution time -- <span class="hljs-subst">{original_sd}</span> ms\\n&quot;</span>)
<span class="hljs-string">&quot;Execution time -- 45781.5 ms&quot;</span>`}}),B=new q({props:{code:"c3RhcnQlMjAlM0QlMjB0aW1lLnRpbWVfbnMoKSUwQWZvciUyMF8lMjBpbiUyMHJhbmdlKE5VTV9JVEVSU19UT19SVU4pJTNBJTBBJTIwJTIwJTIwJTIwaW1hZ2VzJTIwJTNEJTIwZGlzdGlsbGVkKCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHByb21wdCUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG51bV9pbmZlcmVuY2Vfc3RlcHMlM0ROVU1fSU5GRVJFTkNFX1NURVBTJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZ2VuZXJhdG9yJTNEZ2VuZXJhdG9yJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwbnVtX2ltYWdlc19wZXJfcHJvbXB0JTNETlVNX0lNQUdFU19QRVJfUFJPTVBUJTBBJTIwJTIwJTIwJTIwKS5pbWFnZXMlMEFlbmQlMjAlM0QlMjB0aW1lLnRpbWVfbnMoKSUwQSUwQWRpc3RpbGxlZF9zZCUyMCUzRCUyMGYlMjIlN0IoZW5kJTIwLSUyMHN0YXJ0KSUyMCUyRiUyMDFlNiUzQS4xZiU3RCUyMiUwQXByaW50KGYlMjJFeGVjdXRpb24lMjB0aW1lJTIwLS0lMjAlN0JkaXN0aWxsZWRfc2QlN0QlMjBtcyU1Q24lMjIpJTBBJTIyRXhlY3V0aW9uJTIwdGltZSUyMC0tJTIwMjk4ODQuMiUyMG1zJTIy",highlighted:`start = time.time_ns()
<span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(NUM_ITERS_TO_RUN):
images = distilled(
prompt,
num_inference_steps=NUM_INFERENCE_STEPS,
generator=generator,
num_images_per_prompt=NUM_IMAGES_PER_PROMPT
).images
end = time.time_ns()
distilled_sd = <span class="hljs-string">f&quot;<span class="hljs-subst">{(end - start) / <span class="hljs-number">1e6</span>:<span class="hljs-number">.1</span>f}</span>&quot;</span>
<span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Execution time -- <span class="hljs-subst">{distilled_sd}</span> ms\\n&quot;</span>)
<span class="hljs-string">&quot;Execution time -- 29884.2 ms&quot;</span>`}}),S=new Ee({}),k=new q({props:{code:"ZnJvbSUyMGRpZmZ1c2VycyUyMGltcG9ydCUyMEF1dG9lbmNvZGVyVGlueSUwQSUwQWRpc3RpbGxlZC52YWUlMjAlM0QlMjBBdXRvZW5jb2RlclRpbnkuZnJvbV9wcmV0cmFpbmVkKCUwQSUyMCUyMCUyMCUyMCUyMnNheWFrcGF1bCUyRnRhZXNkLWRpZmZ1c2VycyUyMiUyQyUyMHRvcmNoX2R0eXBlJTNEdG9yY2guZmxvYXQxNiUyQyUyMHVzZV9zYWZldGVuc29ycyUzRFRydWUlMkMlMEEpLnRvKCUyMmN1ZGElMjIp",highlighted:`<span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> AutoencoderTiny
distilled.vae = AutoencoderTiny.from_pretrained(
<span class="hljs-string">&quot;sayakpaul/taesd-diffusers&quot;</span>, torch_dtype=torch.float16, use_safetensors=<span class="hljs-literal">True</span>,
).to(<span class="hljs-string">&quot;cuda&quot;</span>)`}}),$=new q({props:{code:"c3RhcnQlMjAlM0QlMjB0aW1lLnRpbWVfbnMoKSUwQWZvciUyMF8lMjBpbiUyMHJhbmdlKE5VTV9JVEVSU19UT19SVU4pJTNBJTBBJTIwJTIwJTIwJTIwaW1hZ2VzJTIwJTNEJTIwZGlzdGlsbGVkKCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHByb21wdCUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG51bV9pbmZlcmVuY2Vfc3RlcHMlM0ROVU1fSU5GRVJFTkNFX1NURVBTJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZ2VuZXJhdG9yJTNEZ2VuZXJhdG9yJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwbnVtX2ltYWdlc19wZXJfcHJvbXB0JTNETlVNX0lNQUdFU19QRVJfUFJPTVBUJTBBJTIwJTIwJTIwJTIwKS5pbWFnZXMlMEFlbmQlMjAlM0QlMjB0aW1lLnRpbWVfbnMoKSUwQSUwQWRpc3RpbGxlZF90aW55X3NkJTIwJTNEJTIwZiUyMiU3QihlbmQlMjAtJTIwc3RhcnQpJTIwJTJGJTIwMWU2JTNBLjFmJTdEJTIyJTBBcHJpbnQoZiUyMkV4ZWN1dGlvbiUyMHRpbWUlMjAtLSUyMCU3QmRpc3RpbGxlZF90aW55X3NkJTdEJTIwbXMlNUNuJTIyKSUwQSUyMkV4ZWN1dGlvbiUyMHRpbWUlMjAtLSUyMDI3MTY1LjclMjBtcyUyMg==",highlighted:`start = time.time_ns()
<span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(NUM_ITERS_TO_RUN):
images = distilled(
prompt,
num_inference_steps=NUM_INFERENCE_STEPS,
generator=generator,
num_images_per_prompt=NUM_IMAGES_PER_PROMPT
).images
end = time.time_ns()
distilled_tiny_sd = <span class="hljs-string">f&quot;<span class="hljs-subst">{(end - start) / <span class="hljs-number">1e6</span>:<span class="hljs-number">.1</span>f}</span>&quot;</span>
<span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Execution time -- <span class="hljs-subst">{distilled_tiny_sd}</span> ms\\n&quot;</span>)
<span class="hljs-string">&quot;Execution time -- 27165.7 ms&quot;</span>`}}),{c(){p=i("meta"),j=n(),r=i("h1"),u=i("a"),X=i("span"),f(_.$$.fragment),ue=n(),x=i("span"),x.textContent=fe,Y=n(),f(V.$$.fragment),D=n(),E=i("p"),E.innerHTML=Me,z=n(),f(w.$$.fragment),L=n(),v=i("p"),v.textContent=Te,K=n(),f(Z.$$.fragment),O=n(),C=i("p"),C.textContent=ye,ee=n(),f(N.$$.fragment),te=n(),R=i("p"),R.textContent=Je,se=n(),f(B.$$.fragment),le=n(),b=i("div"),b.innerHTML=he,ne=n(),m=i("h2"),g=i("a"),P=i("span"),f(S.$$.fragment),me=n(),A=i("span"),A.textContent=Ue,ae=n(),Q=i("p"),Q.innerHTML=we,ie=n(),f(k.$$.fragment),oe=n(),W=i("p"),W.textContent=be,pe=n(),f($.$$.fragment),re=n(),I=i("div"),I.innerHTML=ge,this.h()},l(e){const t=Be("svelte-1phssyn",document.head);p=o(t,"META",{name:!0,content:!0}),t.forEach(s),j=a(e),r=o(e,"H1",{class:!0});var G=F(r);u=o(G,"A",{id:!0,class:!0,href:!0});var Ie=F(u);X=o(Ie,"SPAN",{});var je=F(X);M(_.$$.fragment,je),je.forEach(s),Ie.forEach(s),ue=a(G),x=o(G,"SPAN",{"data-svelte-h":!0}),c(x)!=="svelte-1liex4e"&&(x.textContent=fe),G.forEach(s),Y=a(e),M(V.$$.fragment,e),D=a(e),E=o(e,"P",{"data-svelte-h":!0}),c(E)!=="svelte-12qm2ae"&&(E.innerHTML=Me),z=a(e),M(w.$$.fragment,e),L=a(e),v=o(e,"P",{"data-svelte-h":!0}),c(v)!=="svelte-vjfb98"&&(v.textContent=Te),K=a(e),M(Z.$$.fragment,e),O=a(e),C=o(e,"P",{"data-svelte-h":!0}),c(C)!=="svelte-8we0fz"&&(C.textContent=ye),ee=a(e),M(N.$$.fragment,e),te=a(e),R=o(e,"P",{"data-svelte-h":!0}),c(R)!=="svelte-ovey6g"&&(R.textContent=Je),se=a(e),M(B.$$.fragment,e),le=a(e),b=o(e,"DIV",{class:!0,"data-svelte-h":!0}),c(b)!=="svelte-1jk7wa2"&&(b.innerHTML=he),ne=a(e),m=o(e,"H2",{class:!0});var ce=F(m);g=o(ce,"A",{id:!0,class:!0,href:!0});var _e=F(g);P=o(_e,"SPAN",{});var Ve=F(P);M(S.$$.fragment,Ve),Ve.forEach(s),_e.forEach(s),me=a(ce),A=o(ce,"SPAN",{"data-svelte-h":!0}),c(A)!=="svelte-qtqsf4"&&(A.textContent=Ue),ce.forEach(s),ae=a(e),Q=o(e,"P",{"data-svelte-h":!0}),c(Q)!=="svelte-160eppo"&&(Q.innerHTML=we),ie=a(e),M(k.$$.fragment,e),oe=a(e),W=o(e,"P",{"data-svelte-h":!0}),c(W)!=="svelte-5vjlmh"&&(W.textContent=be),pe=a(e),M($.$$.fragment,e),re=a(e),I=o(e,"DIV",{class:!0,"data-svelte-h":!0}),c(I)!=="svelte-1h7zr2v"&&(I.innerHTML=ge),this.h()},h(){d(p,"name","hf:doc:metadata"),d(p,"content",JSON.stringify($e)),d(u,"id","distilled-stable-diffusion-inference"),d(u,"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"),d(u,"href","#distilled-stable-diffusion-inference"),d(r,"class","relative group"),d(b,"class","flex gap-4"),d(g,"id","tiny-autoencoder"),d(g,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),d(g,"href","#tiny-autoencoder"),d(m,"class","relative group"),d(I,"class","flex justify-center")},m(e,t){T(document.head,p),l(e,j,t),l(e,r,t),T(r,u),T(u,X),y(_,X,null),T(r,ue),T(r,x),l(e,Y,t),y(V,e,t),l(e,D,t),l(e,E,t),l(e,z,t),y(w,e,t),l(e,L,t),l(e,v,t),l(e,K,t),y(Z,e,t),l(e,O,t),l(e,C,t),l(e,ee,t),y(N,e,t),l(e,te,t),l(e,R,t),l(e,se,t),y(B,e,t),l(e,le,t),l(e,b,t),l(e,ne,t),l(e,m,t),T(m,g),T(g,P),y(S,P,null),T(m,me),T(m,A),l(e,ae,t),l(e,Q,t),l(e,ie,t),y(k,e,t),l(e,oe,t),l(e,W,t),l(e,pe,t),y($,e,t),l(e,re,t),l(e,I,t),de=!0},p(e,[t]){const G={};t&2&&(G.$$scope={dirty:t,ctx:e}),w.$set(G)},i(e){de||(J(_.$$.fragment,e),J(V.$$.fragment,e),J(w.$$.fragment,e),J(Z.$$.fragment,e),J(N.$$.fragment,e),J(B.$$.fragment,e),J(S.$$.fragment,e),J(k.$$.fragment,e),J($.$$.fragment,e),de=!0)},o(e){h(_.$$.fragment,e),h(V.$$.fragment,e),h(w.$$.fragment,e),h(Z.$$.fragment,e),h(N.$$.fragment,e),h(B.$$.fragment,e),h(S.$$.fragment,e),h(k.$$.fragment,e),h($.$$.fragment,e),de=!1},d(e){e&&(s(j),s(r),s(Y),s(D),s(E),s(z),s(L),s(v),s(K),s(O),s(C),s(ee),s(te),s(R),s(se),s(le),s(b),s(ne),s(m),s(ae),s(Q),s(ie),s(oe),s(W),s(pe),s(re),s(I)),s(p),U(_),U(V,e),U(w,e),U(Z,e),U(N,e),U(B,e),U(S),U(k,e),U($,e)}}}const $e={local:"distilled-stable-diffusion-inference",sections:[{local:"tiny-autoencoder",title:"Tiny AutoEncoder"}],title:"Distilled Stable Diffusion inference"};function Ge(H){return Ze(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class He extends Ne{constructor(p){super(),Re(this,p,Ge,We,ve,{})}}export{He as component};

Xet Storage Details

Size:
15.9 kB
·
Xet hash:
987bbdaff8f19dbc91d5e84d6b850f83b7e44501ae6c1c1072e44d63864a3260

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