Buckets:
| import{s as ae,o as ie}from"../chunks/scheduler.893fe8c9.js";import{S as $e,i as me,e as O,s as m,c as p,h as se,a as V,d as n,b as s,f as re,g as o,j as fe,k as ne,l as le,m as i,n as c,o as f,q as pe,t as l,p as u,r as oe}from"../chunks/index.2d09ebb4.js";import{C as ce,H as q,E as ue}from"../chunks/MermaidChart.svelte_svelte_type_style_lang.d1e3ca57.js";import{C as xe}from"../chunks/CourseFloatingBanner.e3aeab73.js";import{Q as U}from"../chunks/Question.6e77d2db.js";import{F as ge}from"../chunks/FrameworkSwitchCourse.f49b9dc4.js";function de(N){let x,h,g,y,d,S,_,C,b,P,w,k;return x=new q({props:{title:"4. Что происходит, когда вы создаете экземпляр одного из классов TFAutoModelForXxx с предварительно обученной языковой моделью (например, bert-base-uncased ), которая соответствует задаче, отличной от той, для которой она была обучена?",local:"4-что-происходит-когда-вы-создаете-экземпляр-одного-из-классов-tfautomodelforxxx-с-предварительно-обученной-языковой-моделью-например-bert-base-uncased--которая-соответствует-задаче-отличной-от-той-для-которой-она-была-обучена",headingTag:"h3"}}),g=new U({props:{choices:[{text:"Ничего, но будет выведено предупреждение.",explain:"Предупреждение действительно появится, но это не всё!"},{text:"Последний слой модели будет заменён на слой, подходящий для текущей задачи.",explain:"Правильно. Например, когда мы используем <code>AutoModelForSequenceClassification</code> с <code>bert-base-uncased</code> чекпоинтом, распечатывается предупреждение при инициализации модели. Предобученная «голова» модели не используется для классификации предложений, так что она заменяется другим слоем со случайно инициализированными весами.",correct:!0},{text:"Последний слой модели игнорируется.",explain:"Должно произойти что-то еще! Попробуй еще раз!"},{text:"Ничего, модель по-прежнему можно будет настроить на решение другой задачи.",explain:"Последний слой модели был обучен решать другую задачу, значит с ним должно что-то произойти!"}]}}),d=new q({props:{title:"5. TensorFlow-модели из transformers уже можно рассматривать как Keras-модели. Какие преимущества это дает?",local:"5-tensorflow-модели-из-transformers-уже-можно-рассматривать-как-keras-модели-какие-преимущества-это-дает",headingTag:"h3"}}),_=new U({props:{choices:[{text:"Модели будут работать на TPU «из коробки».",explain:"Почти! Необходимо внести ряд дополнительных изменений, например: следует запустить все с помощью <code>TPUStrategy</code> (включая инициализацию модели)."},{text:"Вы сможете испольовать существующие методы, такие как <code>compile()</code>, <code>fit()</code> и <code>predict()</code>.",explain:"Верно! Данные у вас уже есть, дело осталось за малым – обучить модель. ",correct:!0},{text:"Вы сможете изучить и Keras, и transformers.",explain:"Верно! Но ответ все же немного другой :)",correct:!0},{text:"Вы можете просто вычислить метрики, связанные с датасетом.",explain:"Keras помогает в обучении и валидации модели, а не с вычислением метрик."}]}}),b=new q({props:{title:"6. Как мы можем задать собственную метрику?",local:"6-как-мы-можем-задать-собственную-метрику",headingTag:"h3"}}),w=new U({props:{choices:[{text:"Наследуя <code>tf.keras.metrics.Metric</code>.",explain:"Великолепно!",correct:!0},{text:"С использованием функционального API Keras.",explain:"Try again!"},{text:"С использованием вызываемого модуля <code>metric_fn(y_true, y_pred)</code>.",explain:"Верно!",correct:!0},{text:"Загуглив её!",explain:"Это не тот ответ, который мы ожидаем, однако это должно помочь вам!",correct:!0}]}}),{c(){p(x.$$.fragment),h=m(),p(g.$$.fragment),y=m(),p(d.$$.fragment),S=m(),p(_.$$.fragment),C=m(),p(b.$$.fragment),P=m(),p(w.$$.fragment)},l(r){o(x.$$.fragment,r),h=s(r),o(g.$$.fragment,r),y=s(r),o(d.$$.fragment,r),S=s(r),o(_.$$.fragment,r),C=s(r),o(b.$$.fragment,r),P=s(r),o(w.$$.fragment,r)},m(r,T){c(x,r,T),i(r,h,T),c(g,r,T),i(r,y,T),c(d,r,T),i(r,S,T),c(_,r,T),i(r,C,T),c(b,r,T),i(r,P,T),c(w,r,T),k=!0},i(r){k||(l(x.$$.fragment,r),l(g.$$.fragment,r),l(d.$$.fragment,r),l(_.$$.fragment,r),l(b.$$.fragment,r),l(w.$$.fragment,r),k=!0)},o(r){f(x.$$.fragment,r),f(g.$$.fragment,r),f(d.$$.fragment,r),f(_.$$.fragment,r),f(b.$$.fragment,r),f(w.$$.fragment,r),k=!1},d(r){r&&(n(h),n(y),n(S),n(C),n(P)),u(x,r),u(g,r),u(d,r),u(_,r),u(b,r),u(w,r)}}}function _e(N){let x,h,g,y,d,S,_,C,b,P,w,k,r,T,A,E,F,M,L,v,z,H,D,K;return x=new q({props:{title:"4. Какие преимущества есть у метода Dataset.map()?",local:"4-какие-преимущества-есть-у-метода-datasetmap",headingTag:"h3"}}),g=new U({props:{choices:[{text:"Результаты функции кэшируются, поэтому повторное выполнение кода не займет много времени.",explain:"Это действительно одно из преимуществ этого метода! Впрочем, не единственное...",correct:!0},{text:"Можно применить мультипроцессорную обработку – это быстрее, чем применять функцию к каждому элементу выборки.",explain:"Это преимущество данного метода, но не единственное.",correct:!0},{text:"Он не загружает весь набор данных в память, сохраняя результаты сразу после обработки одного элемента.",explain:"Это одно из преимуществ этого метода. Хотя есть и другие!",correct:!0}]}}),d=new q({props:{title:"5. Что такое dynamic padding?",local:"5-что-такое-dynamic-padding",headingTag:"h3"}}),_=new U({props:{choices:[{text:"Дополнение нулями каждой входной последовательности до максимальной длины, содержащейся в датасете.",explain:"Подразумевает дополнение при создании батча, но не до максимальной длины во всем датасете."},{text:"Дополнение нулями при создании батча до максимальной длины предложения, содержашегося в батче.",explain:'Правильно! "Динамическим" пэддинг становится в момент анализа каждого элемента батча. Все батчи могут иметь разную длину элементов.',correct:!0},{text:"Такое дополнение, при котором длина каждого предложения равна длине предыдущего предложения.",explain:"Неправильно. Хотя бы потому, что мы перемешиваем датасет во время обучения."}]}}),b=new q({props:{title:"6. Какова цель функции сопоставления (collate function)?",local:"6-какова-цель-функции-сопоставления-collate-function",headingTag:"h3"}}),w=new U({props:{choices:[{text:"Она проверяет, что все предложения в датасете одинаковой длины.",explain:"Функция сопоставления используется для обработки отдельных батчей, а не всего датасета. Кроме того, мы говорим об общих collate-функциях, а не конкретно о <code>DataCollatorWithPadding</code>."},{text:"Она соединяет вместе все элементы батча.",explain:"Верно! Вы можете передать функцию сопоставления в качестве аргумента для <code>DataLoader</code>. Мы использовали функцию <code>DataCollatorWithPadding</code>, которая дополняет все элементы в батче до одинаковой длины.",correct:!0},{text:"Она обрабатывает весь датасет. ",explain:"Тогда она называлась быть функцией препроцессинга, а не функцией сопоставления."},{text:"Она обрезает предложения в датасете.",explain:"Collate-функция используется для одного батча, а не всего датасета. Если вам необходимо обрезать датасет, вы можете использовать аргумент <code>truncate</code> в <code>tokenizer</code>."}]}}),r=new q({props:{title:"7. Что происходит, когда вы создаете экземпляр одного из классов AutoModelForXxx с предварительно обученной языковой моделью (например, bert-base-uncased ), которая соответствует задаче, отличной от той, для которой она была обучена?",local:"7-что-происходит-когда-вы-создаете-экземпляр-одного-из-классов-automodelforxxx-с-предварительно-обученной-языковой-моделью-например-bert-base-uncased--которая-соответствует-задаче-отличной-от-той-для-которой-она-была-обучена",headingTag:"h3"}}),A=new U({props:{choices:[{text:"Ничего, но будет выведено предупреждение.",explain:"Предупреждение действительно появится, но это не всё!"},{text:"Последний слой модели будет заменён на слой, подходящий для текущей задачи.",explain:"Правильно. Например, когда мы используем <code>AutoModelForSequenceClassification</code> с <code>bert-base-uncased</code> чекпоинтом, распечатывается предупреждение при инициализации модели. Предобученная «голова» модели не используется для классификации предложений, так что она заменяется другим слоем со случайно инициализированными весами.",correct:!0},{text:"Последний слой модели игнорируется.",explain:"Должно произойти что-то еще! Попробуй еще раз!"},{text:"Ничего, модель по-прежнему можно будет настроить на решение другой задачи.",explain:"Последний слой модели был обучен решать другую задачу, значит с ним должно что-то произойти!"}]}}),F=new q({props:{title:"8. Зачем нужен TrainingArguments ?",local:"8-зачем-нужен-trainingarguments-",headingTag:"h3"}}),L=new U({props:{choices:[{text:"Он содержит все гиперпараметры, используемые для обучения и оценки с помощью <code>Trainer</code>",explain:"Верно!",correct:!0},{text:"Задает размер модели.",explain:"Размер модели определяется ее структурой, а не классом <code>TrainingArguments</code>."},{text:"Содержит гиперпараметры для этапа валидации модели.",explain:"В примере мы задавали, где будут сохраняться модель и её веса. Попробуй еще раз!"},{text:"Он содержит гиперпараметры этапа обучения.",explain:"В примере мы использовали <code>evaluation_strategy</code>, что также влияет на валидацию. Попробуй еще раз!"}]}}),z=new q({props:{title:"9. Зачем нужна библиотека 🤗 Accelerate?",local:"9-зачем-нужна-библиотека--accelerate",headingTag:"h3"}}),D=new U({props:{choices:[{text:"Предоставляет доступ к более быстрым моделям.",explain:"Нет, 🤗 Accelerate не предоставляет доступа к каким-либо ни было моделям."},{text:"Предоставляет высокоуровневый API и появляется возможность не реализовывать собственный цикл обучения.",explain:"Это мы делаем с помощью <code>Trainer</code>, а не 🤗 Accelerate. Попробуй еще раз!"},{text:"Позволяет исполнить наш цикл обучения на распределенных системах.",explain:"Праивльно! С помощью 🤗 Accelerate обучающий цикл будет исполняться на нескольких GPU или TPU.",correct:!0},{text:"Предоставляет больше оптимизационных функций.",explain:"Нет, 🤗 Accelerate не предоставляет оптимизационных функций."}]}}),{c(){p(x.$$.fragment),h=m(),p(g.$$.fragment),y=m(),p(d.$$.fragment),S=m(),p(_.$$.fragment),C=m(),p(b.$$.fragment),P=m(),p(w.$$.fragment),k=m(),p(r.$$.fragment),T=m(),p(A.$$.fragment),E=m(),p(F.$$.fragment),M=m(),p(L.$$.fragment),v=m(),p(z.$$.fragment),H=m(),p(D.$$.fragment)},l(t){o(x.$$.fragment,t),h=s(t),o(g.$$.fragment,t),y=s(t),o(d.$$.fragment,t),S=s(t),o(_.$$.fragment,t),C=s(t),o(b.$$.fragment,t),P=s(t),o(w.$$.fragment,t),k=s(t),o(r.$$.fragment,t),T=s(t),o(A.$$.fragment,t),E=s(t),o(F.$$.fragment,t),M=s(t),o(L.$$.fragment,t),v=s(t),o(z.$$.fragment,t),H=s(t),o(D.$$.fragment,t)},m(t,$){c(x,t,$),i(t,h,$),c(g,t,$),i(t,y,$),c(d,t,$),i(t,S,$),c(_,t,$),i(t,C,$),c(b,t,$),i(t,P,$),c(w,t,$),i(t,k,$),c(r,t,$),i(t,T,$),c(A,t,$),i(t,E,$),c(F,t,$),i(t,M,$),c(L,t,$),i(t,v,$),c(z,t,$),i(t,H,$),c(D,t,$),K=!0},i(t){K||(l(x.$$.fragment,t),l(g.$$.fragment,t),l(d.$$.fragment,t),l(_.$$.fragment,t),l(b.$$.fragment,t),l(w.$$.fragment,t),l(r.$$.fragment,t),l(A.$$.fragment,t),l(F.$$.fragment,t),l(L.$$.fragment,t),l(z.$$.fragment,t),l(D.$$.fragment,t),K=!0)},o(t){f(x.$$.fragment,t),f(g.$$.fragment,t),f(d.$$.fragment,t),f(_.$$.fragment,t),f(b.$$.fragment,t),f(w.$$.fragment,t),f(r.$$.fragment,t),f(A.$$.fragment,t),f(F.$$.fragment,t),f(L.$$.fragment,t),f(z.$$.fragment,t),f(D.$$.fragment,t),K=!1},d(t){t&&(n(h),n(y),n(S),n(C),n(P),n(k),n(T),n(E),n(M),n(v),n(H)),u(x,t),u(g,t),u(d,t),u(_,t),u(b,t),u(w,t),u(r,t),u(A,t),u(F,t),u(L,t),u(z,t),u(D,t)}}}function be(N){let x,h,g,y,d,S,_,C,b,P,w,k,r,T="Тест по результатам изучения главы 3.",A,E,F,M,L,v,z,H,D,K,t,$,W,X,B,G,Q,j,I,J;d=new ge({props:{fw:N[0]}}),_=new ce({props:{containerStyle:"float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"}}),b=new q({props:{title:"Тест в конце главы",local:"end-of-chapter-quiz",headingTag:"h1"}}),w=new xe({props:{chapter:3,classNames:"absolute z-10 right-0 top-0"}}),E=new q({props:{title:"Датасет emotion содержит сообщения из Твиттера, каждое сообщение помечено какой-либо эмоцией. Найдите его на Hub и изучить карточку датасета. Какая из этих эмоцией не является базовой?",local:"датасет-emotion-содержит-сообщения-из-твиттера-каждое-сообщение-помечено-какой-либо-эмоцией-найдите-его-на-hub-и-изучить-карточку-датасета-какая-из-этих-эмоцией-не-является-базовой",headingTag:"h3"}}),M=new U({props:{choices:[{text:"Joy",explain:"Попробуйте еще раз, этот класс присутствует в датасете!"},{text:"Love",explain:"Попробуйте еще раз, этот класс присутствует в датасете!"},{text:"Confusion",explain:"Правильно! Замешательство не является одним из 6 базовых классов датасета.",correct:!0},{text:"Surprise",explain:"Сюрприз! Попробуйте другой вариант!"}]}}),v=new q({props:{title:"2. Найдите датасет ar_sarcasm в Hub . Какую задачу можно решить с использованием этого датасета?",local:"2-найдите-датасет-arsarcasm-в-hub--какую-задачу-можно-решить-с-использованием-этого-датасета",headingTag:"h3"}}),H=new U({props:{choices:[{text:"Sentiment classification / Классификация тональности",explain:"Правильно! Поблагодарите за это тэги. ",correct:!0},{text:"Machine translation / Машинный перевод",explain:"Нет, изучите еще раз <a href='https://huggingface.co/datasets/ar_sarcasm'>карточку</a> датасета!"},{text:"Named entity recognition / Распознавание именованных сущностей",explain:"Нет, изучите еще раз <a href='https://huggingface.co/datasets/ar_sarcasm'>карточку</a> датасета!"},{text:"Question answering / Ответы на вопросы",explain:"Увы! Неправильный ответ. "}]}}),K=new q({props:{title:"3. В каком формате модель BERT ожидает на вход пару предложений?",local:"3-в-каком-формате-модель-bert-ожидает-на-вход-пару-предложений",headingTag:"h3"}}),$=new U({props:{choices:[{text:"Токены_предложения_1 [SEP] Токены_предложения_2",explain:"Токен <code>[SEP]</code> – специальный токен для разделения двух предложений, однако этого недостаточно."},{text:"[CLS] Токены_предложения_1 Токены_предложения_2",explain:"Токен <code>[CLS]</code> – специальный токен, обозначающий начало последовательнсти, однако этого недостаточно."},{text:"[CLS] Токены_предложения_1 [SEP] Токены_предложения_2 [SEP]",explain:"Правильно!",correct:!0},{text:"[CLS] Токены_предложения_1 [SEP] Токены_предложения_2",explain:"Токен <code>[CLS]</code> – специальный токен, обозначающий начало последовательнсти, Токен <code>[SEP]</code> – специальный токен для разделения двух предложений. Но это не всё!"}]}});const Z=[_e,de],R=[];function ee(e,a){return e[0]==="pt"?0:1}return X=ee(N),B=R[X]=Z[X](N),Q=new ue({props:{source:"https://github.com/huggingface/course/blob/main/chapters/ru/chapter3/6.mdx"}}),{c(){x=O("meta"),h=m(),g=O("p"),y=m(),p(d.$$.fragment),S=m(),p(_.$$.fragment),C=m(),p(b.$$.fragment),P=m(),p(w.$$.fragment),k=m(),r=O("p"),r.textContent=T,A=m(),p(E.$$.fragment),F=m(),p(M.$$.fragment),L=m(),p(v.$$.fragment),z=m(),p(H.$$.fragment),D=m(),p(K.$$.fragment),t=m(),p($.$$.fragment),W=m(),B.c(),G=m(),p(Q.$$.fragment),j=m(),I=O("p"),this.h()},l(e){const a=se("svelte-u9bgzb",document.head);x=V(a,"META",{name:!0,content:!0}),a.forEach(n),h=s(e),g=V(e,"P",{}),re(g).forEach(n),y=s(e),o(d.$$.fragment,e),S=s(e),o(_.$$.fragment,e),C=s(e),o(b.$$.fragment,e),P=s(e),o(w.$$.fragment,e),k=s(e),r=V(e,"P",{"data-svelte-h":!0}),fe(r)!=="svelte-13nekar"&&(r.textContent=T),A=s(e),o(E.$$.fragment,e),F=s(e),o(M.$$.fragment,e),L=s(e),o(v.$$.fragment,e),z=s(e),o(H.$$.fragment,e),D=s(e),o(K.$$.fragment,e),t=s(e),o($.$$.fragment,e),W=s(e),B.l(e),G=s(e),o(Q.$$.fragment,e),j=s(e),I=V(e,"P",{}),re(I).forEach(n),this.h()},h(){ne(x,"name","hf:doc:metadata"),ne(x,"content",we)},m(e,a){le(document.head,x),i(e,h,a),i(e,g,a),i(e,y,a),c(d,e,a),i(e,S,a),c(_,e,a),i(e,C,a),c(b,e,a),i(e,P,a),c(w,e,a),i(e,k,a),i(e,r,a),i(e,A,a),c(E,e,a),i(e,F,a),c(M,e,a),i(e,L,a),c(v,e,a),i(e,z,a),c(H,e,a),i(e,D,a),c(K,e,a),i(e,t,a),c($,e,a),i(e,W,a),R[X].m(e,a),i(e,G,a),c(Q,e,a),i(e,j,a),i(e,I,a),J=!0},p(e,[a]){const te={};a&1&&(te.fw=e[0]),d.$set(te);let Y=X;X=ee(e),X!==Y&&(oe(),f(R[Y],1,1,()=>{R[Y]=null}),pe(),B=R[X],B||(B=R[X]=Z[X](e),B.c()),l(B,1),B.m(G.parentNode,G))},i(e){J||(l(d.$$.fragment,e),l(_.$$.fragment,e),l(b.$$.fragment,e),l(w.$$.fragment,e),l(E.$$.fragment,e),l(M.$$.fragment,e),l(v.$$.fragment,e),l(H.$$.fragment,e),l(K.$$.fragment,e),l($.$$.fragment,e),l(B),l(Q.$$.fragment,e),J=!0)},o(e){f(d.$$.fragment,e),f(_.$$.fragment,e),f(b.$$.fragment,e),f(w.$$.fragment,e),f(E.$$.fragment,e),f(M.$$.fragment,e),f(v.$$.fragment,e),f(H.$$.fragment,e),f(K.$$.fragment,e),f($.$$.fragment,e),f(B),f(Q.$$.fragment,e),J=!1},d(e){e&&(n(h),n(g),n(y),n(S),n(C),n(P),n(k),n(r),n(A),n(F),n(L),n(z),n(D),n(t),n(W),n(G),n(j),n(I)),n(x),u(d,e),u(_,e),u(b,e),u(w,e),u(E,e),u(M,e),u(v,e),u(H,e),u(K,e),u($,e),R[X].d(e),u(Q,e)}}}const we='{"title":"Тест в конце главы","local":"end-of-chapter-quiz","sections":[{"title":"Датасет emotion содержит сообщения из Твиттера, каждое сообщение помечено какой-либо эмоцией. Найдите его на Hub и изучить карточку датасета. Какая из этих эмоцией не является базовой?","local":"датасет-emotion-содержит-сообщения-из-твиттера-каждое-сообщение-помечено-какой-либо-эмоцией-найдите-его-на-hub-и-изучить-карточку-датасета-какая-из-этих-эмоцией-не-является-базовой","sections":[],"depth":3},{"title":"2. Найдите датасет ar_sarcasm в Hub . Какую задачу можно решить с использованием этого датасета?","local":"2-найдите-датасет-arsarcasm-в-hub--какую-задачу-можно-решить-с-использованием-этого-датасета","sections":[],"depth":3},{"title":"3. В каком формате модель BERT ожидает на вход пару предложений?","local":"3-в-каком-формате-модель-bert-ожидает-на-вход-пару-предложений","sections":[],"depth":3},{"title":"4. Какие преимущества есть у метода Dataset.map()?","local":"4-какие-преимущества-есть-у-метода-datasetmap","sections":[],"depth":3},{"title":"5. Что такое dynamic padding?","local":"5-что-такое-dynamic-padding","sections":[],"depth":3},{"title":"6. Какова цель функции сопоставления (collate function)?","local":"6-какова-цель-функции-сопоставления-collate-function","sections":[],"depth":3},{"title":"7. Что происходит, когда вы создаете экземпляр одного из классов AutoModelForXxx с предварительно обученной языковой моделью (например, bert-base-uncased ), которая соответствует задаче, отличной от той, для которой она была обучена?","local":"7-что-происходит-когда-вы-создаете-экземпляр-одного-из-классов-automodelforxxx-с-предварительно-обученной-языковой-моделью-например-bert-base-uncased--которая-соответствует-задаче-отличной-от-той-для-которой-она-была-обучена","sections":[],"depth":3},{"title":"8. Зачем нужен TrainingArguments ?","local":"8-зачем-нужен-trainingarguments-","sections":[],"depth":3},{"title":"9. Зачем нужна библиотека 🤗 Accelerate?","local":"9-зачем-нужна-библиотека--accelerate","sections":[],"depth":3},{"title":"4. Что происходит, когда вы создаете экземпляр одного из классов TFAutoModelForXxx с предварительно обученной языковой моделью (например, bert-base-uncased ), которая соответствует задаче, отличной от той, для которой она была обучена?","local":"4-что-происходит-когда-вы-создаете-экземпляр-одного-из-классов-tfautomodelforxxx-с-предварительно-обученной-языковой-моделью-например-bert-base-uncased--которая-соответствует-задаче-отличной-от-той-для-которой-она-была-обучена","sections":[],"depth":3},{"title":"5. TensorFlow-модели из transformers уже можно рассматривать как Keras-модели. Какие преимущества это дает?","local":"5-tensorflow-модели-из-transformers-уже-можно-рассматривать-как-keras-модели-какие-преимущества-это-дает","sections":[],"depth":3},{"title":"6. Как мы можем задать собственную метрику?","local":"6-как-мы-можем-задать-собственную-метрику","sections":[],"depth":3}],"depth":1}';function Te(N,x,h){let g="pt";return ie(()=>{const y=new URLSearchParams(window.location.search);h(0,g=y.get("fw")||"pt")}),[g]}class qe extends $e{constructor(x){super(),me(this,x,Te,be,ae,{})}}export{qe as component}; | |
Xet Storage Details
- Size:
- 27.8 kB
- Xet hash:
- 15d254e6fc07ba2da032e59c39793d24fe3666bf863ca9c62df75d0a95d9985b
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.