Короткий ответ, который экономит кучу времени: датасет с Hugging Face обычно не «скачивают» файлами вручную, а подтягивают библиотекой `datasets` одной строкой. Ставишь `pip install datasets`, пишешь `load_dataset("имя/датасета")` — и данные уже в коде, разложенные по частям и готовые к работе. Это не то же самое, что тянуть модель: у датасетов свой инструмент и своя логика, и если пытаться качать их как модель, намучаешься на ровном месте.
Всё это бесплатно: публичные датасеты открыты и качаются без подписки. PRO на площадке нужен для другого — приватного просмотрщика датасетов, большего хранилища и лимитов; оплату в долларах, если карта не проходит, оформляют через SUB.SUP (Telegram или ВКонтакте). Но чтобы просто скачать датасет с Hugging Face, ничего платить не надо.
Датасет здесь — это набор данных для обучения или проверки модели: тексты, картинки, таблицы, аудио, разбитые на строки и колонки. Берут его, чтобы что-то на нём посчитать или чему-то научить модель, а не просто сохранить на диск, — и весь инструмент под это заточен. Разберём, как это работает, как брать не весь набор целиком и что делать с датасетами, которые больше твоего диска.
Датасет — не модель: его берут библиотекой datasets
Первое, что стоит развести в голове: модель и датасет качаются разными инструментами. Модель — через `transformers` или `huggingface_hub`, потому что тебе нужны файлы весов. Датасет — через `datasets`, потому что тебе нужны не файлы сами по себе, а данные, разобранные по строкам и колонкам.
Технически датасеты на площадке чаще всего хранятся в parquet — компактном колоночном формате. Можно, конечно, скачать эти parquet-файлы напрямую хоть кнопкой, хоть через `huggingface_hub` с `repo_type="dataset"`. Но тогда ты получишь просто файлы, которые дальше разбирай сам. Библиотека `datasets` делает это за тебя: качает, парсит, отдаёт готовый объект и, что важно, не держит всё в оперативке — данные лежат на диске в формате Arrow, а в память подтягивается только то, что читаешь прямо сейчас.
Поэтому дальше речь именно про `load_dataset` — идиоматичный способ, которым берут данные девять из десяти.
Одна команда load_dataset
Весь базовый сценарий умещается в пару строк. `from datasets import load_dataset`, потом `ds = load_dataset("stanfordnlp/imdb")` — и готово. Первый раз данные скачаются и лягут в тот же кэш, что и модели, со второго раза подтянутся мгновенно.
Что возвращается — важно понять сразу. Обычно это не единая таблица, а `DatasetDict`: словарь со сплитами, то есть с готовыми частями `train`, `test`, иногда `validation`. Обращаешься к нужной как `ds["train"]`, а дальше — как к таблице: `ds["train"][0]` покажет первую строку, `ds["train"].features` — колонки и их типы, `ds["train"].column_names` — просто имена полей. Никакого ручного парсинга, всё уже разобрано.
С этим объектом сразу удобно работать. Метод `.map()` прогоняет функцию по всем строкам — например, токенизирует тексты; `.filter()` отбирает нужные; `.select(range(1000))` берёт первую тысячу строк. Всё это ленивое и быстрое, потому что под капотом Arrow, а не питоновские списки.
Первым делом после загрузки полезно просто напечатать объект: `print(ds)` покажет, какие есть сплиты, сколько в каждом строк и какие колонки. Тридцать секунд — и перед тобой карта набора, гадать по первым строкам не нужно. Пара удобств, которые ускоряют жизнь дальше: `.map(..., batched=True)` обрабатывает строки пачками, а не по одной, и на токенизации это разница в разы, а `.features` показывает не только имена колонок, но и их типы — где текст, где число, где метка класса со списком значений.
Датасеты бывают устроены сложнее, чем один набор. У многих есть конфигурации — отдельные варианты внутри одного репозитория: языки, версии, поднаборы. Тогда имя конфигурации передают вторым аргументом, например `load_dataset("glue", "mrpc")` или конкретный язык у многоязычного набора. Если не указать, а датасет требует выбора, библиотека честно попросит назвать конфигурацию и перечислит доступные прямо в тексте ошибки — не пугайся, просто выбери из списка.
Сплиты, срезы и конфигурации: как взять только нужную часть данных
Вот где `datasets` реально экономит время и место. Тебе редко нужен весь набор целиком — чаще кусок, и библиотека умеет отдавать ровно его, не скачивая остальное зря.
Сплит выбираешь параметром `split`. `load_dataset("imdb", split="train")` вернёт сразу таблицу train, без обёртки-словаря. А дальше начинается то, ради чего это всё и затевалось, — срезы, которые выглядят как обычные питоновские слайсы. `split="train[:10%]"` — первые десять процентов набора. `split="train[:100]"` — первые сто строк. `split="train[50%:]"` — вторая половина. `split="train+test"` — склеить два сплита в один. Проценты и диапазоны можно комбинировать, из чего собирают, например, разбиения для кросс-валидации.
Нужна не первая часть, а случайная выборка — сначала перемешай с фиксированным зерном, потом бери: `ds["train"].shuffle(seed=42).select(range(1000))` даст воспроизводимую тысячу случайных строк. Зерно тут не для красоты — без него каждый запуск вернёт другую выборку, и результаты перестанут сходиться между прогонами. А выдернуть точечные строки можно списком индексов: `ds.select([0, 5, 999])` вернёт ровно эти три — выручает, когда нашёл в просмотрщике проблемные примеры и хочешь глянуть на них в коде.
Это тот приём, который стоит завести в привычку раз и навсегда. Отлаживаешь пайплайн — берёшь один процент данных, всё летает; убедился, что код рабочий, — снимаешь ограничение и запускаешь на полном наборе. Куча времени экономится ровно на том, что ты не ждёшь загрузки гигабайтов ради проверки опечатки в двух строчках кода. Новички этого не делают и потому сидят, глядя на прогресс-бар, там, где можно было управиться за секунды.
Отдельные файлы и папки адресуются тоже. Параметр `data_files` с маской заберёт конкретные parquet-шарды: на наборе вроде C4 — а это сотни гигабайт текста — качать всё бессмысленно, и `load_dataset("allenai/c4", data_files="en/c4-train.00000-of-01024.json.gz")` возьмёт один файл, которого с головой хватит на эксперименты. Параметр `data_dir` берёт конкретную подпапку — скажем, один язык из многоязычного набора.
А если данные у тебя уже локальные, библиотека соберёт датасет и из них: `load_dataset("csv", data_files="myfile.csv")` для CSV, `json` с указанием поля через `field=`, `parquet` и другие форматы — на выходе тот же удобный объект, что и с Hub. Скормить можно и ссылку: обычный `https://` и адрес вида `hf://datasets/...` работают как источник данных. То есть `datasets` полезна, даже когда ты вообще ничего не берёшь с площадки, а просто удобно возишься со своими таблицами. И про версии, раз зашла речь: у датасета, как у модели, есть ревизии, и `revision=` зафиксирует конкретную — чтобы эксперимент воспроизводился, когда автор обновит данные.
Ещё пара мелочей на будущее. Загрузку большого набора ускоряет параметр `num_proc` — качает и распаковывает в несколько процессов, а не в один. А в память датасет целиком тянуть не обязательно: по умолчанию он лежит на диске в Arrow, но для маленьких наборов, которые гоняешь часто, есть `keep_in_memory=True` — тогда всё держится в оперативке и читается ещё быстрее. Так из простых кубиков — сплит, срез, конкретные файлы, локальные данные — собирается ровно та выборка, что тебе нужна, без лишних гигабайтов на диске и в трафике.
Стриминг для датасета, который не влезает на диск
Теперь про большие данные, ради которых половина сюда и пришла. Некоторые датасеты — это сотни гигабайт и терабайты; скачивать такое целиком невозможно и бессмысленно. Для этого есть режим стриминга.
Добавляешь один параметр: `load_dataset("имя", streaming=True)`. Вместо того чтобы качать весь набор на диск, библиотека читает его по кусочкам прямо на лету — отдаёт строки одну за другой по мере того, как ты их запрашиваешь. На диск при этом почти ничего не оседает. По оценкам самой площадки, для типичных сценариев обучения это в разы эффективнее по месту и времени старта: работа начинается сразу, а не после многочасовой загрузки терабайта, который ты, скорее всего, весь и не прочитаешь.
Разница в объекте важная. Без стриминга ты получаешь таблицу, которую можно индексировать как список и прыгать к любой строке. Со стримингом — итератор: идёшь по нему вперёд методами вроде `.take(1000)` (взять первую тысячу) и `.skip(500)` (пропустить), но обратиться к произвольной строке по номеру уже нельзя. Перемешивание тоже работает иначе — через буфер, а не по всему набору. Для обучения это норма: данные и так читаются потоком, порция за порцией.
Стримить можно и несколько наборов сразу: `interleave_datasets` смешивает потоки в один, что удобно при обучении на смеси источников. А если набор ты всё-таки скачал и гоняешь по нему `.map`, ускорить подготовку помогает `num_proc` — библиотека раскидает работу по нескольким ядрам. На практике стриминговый датасет выглядит как обычный цикл `for row in ds`: идёшь по данным батч за батчем, без единого лишнего гигабайта на диске.
Итого про выбор, качать или стримить. Набор небольшой, нужен целиком и гонять ты будешь его много раз — скачай, на повторах так быстрее. Набор огромный, или тебе хватит куска, или ты просто щупаешь его на пригодность — стримь или бери срез, и не сажай диск. В девяти случаях из десяти новичок недооценивает, сколько всего можно сделать, вообще не скачивая датасет целиком, — и именно в этом главная мысль всей статьи.
Частые вопросы про загрузку датасетов
### Как посмотреть датасет до того, как качать?
Прямо на странице датасета есть встроенный просмотрщик: листаешь строки, видишь колонки и примеры, не скачав ни байта. Заодно там видно размер набора, число строк и распределение по колонкам — по этому сразу ясно, стоит ли вообще тянуть его себе. Это лучший способ понять, подходит ли набор, до всякого кода. У приватных датасетов такой просмотрщик — уже фича PRO.
### Как скачать приватный датасет или свой закрытый?
Так же, как публичный, но с токеном: `hf auth login` в терминале или `token="hf_..."` в вызове, токен бесплатный. А если упрёшься в лимиты хранилища или захочешь приватный просмотрщик и PRO, а российская карта не пройдёт, — оформить подписку помогут в SUB.SUP (Telegram или ВКонтакте).
### В каком формате приходят данные?
Чаще всего на площадке это parquet, но тебе об этом думать почти не нужно: `load_dataset` сам разбирает формат и отдаёт единый объект. Формат всплывает, только если качаешь файлы напрямую в обход библиотеки.
### Можно ли работать с датасетом офлайн?
Да. Один раз скачанный набор ложится в кэш и с включённым офлайн-режимом читается оттуда без сети. Со стримингом так не выйдет — он по определению тянет данные на лету, и интернет ему нужен постоянно.
### datasets и huggingface_hub — это одно и то же?
Нет, но они рядом. `huggingface_hub` — низкоуровневый транспорт, качает любые файлы. `datasets` — надстройка именно под данные: парсит, режет, стримит, отдаёт таблицы. Для датасетов бери `datasets`, для произвольных файлов репозитория — `huggingface_hub`.
Комментарии
Войдите, чтобы написать комментарий