The post has been translated automatically. Original language: Russian
The project is on course, the Transformers track: DistilBERT learns to distinguish good IMDB reviews from bad ones. Students assemble a ModelTrainer class with eleven methods: data loading, training, validation, metrics, logging. There is also a save_model, a tenth of the score for the project. The entire condition fits into the docstring: "Saves model to dst_path". Plus one warning: check if the model is wrapped in a DataParallel.
In 41% of projects, the method is closed with one line: torch.save(model.state_dict()). You can't find fault with the letter: the model is saved in dst_path, the file is on disk, and there is a check mark. After a month, the file is opened. The model is not there.
There is a file. What is missing:
1️⃣ Architecture
state_dict contains only weights, a bare dictionary of tensors: no configuration, no description of layers. You can only load it into a model reassembled by the hands of exactly the same architecture, otherwise the download will not converge in layers.
2️⃣ Tokenizer
The model accepts token indexes, not text. The tokenizer is not saved nearby, which means there is nothing to turn the text into: the information cannot be collected at all. And you need the same one.: the other one has its own "word → number" correspondence.
Irony: the only thing the condition warned about in plain text, almost everything was done — the wrapper was unwrapped. Almost: in one work, the check for DataParallel is written, but the row inside it does not assign anything. The checkmark is on again, the effect is zero again. They broke not where the condition warned, but where it was silent.
Useful habits of ML'shik
Keep the model reloaded. model.save_pretrained(path), from under the wrapper - model.module.save_pretrained(path), and next to it in the same folder tokenizer.save_pretrained(path). Then one from_pretrained(path) raises everything at once: config, architecture, weights, tokenizer, on any machine. It's easy to check: save the checkpoint, restart the session, and raise the model again from disk — from_pretrained(path). Run a few examples through the inference: the predictions must match those that the model produced before saving. Matched — the model was saved, not the file.
Saving a file and saving a model are two different things. The first covers the letter of the condition, the second covers the meaning. And the prod exams without a docstring: he doesn't write warnings, he doesn't give hints, he has one question. Will it load?
Setting such habits is easier in practice: here, the model is considered saved only when it has been lifted on someone else's car.
BigData Team: the way you learn best
Проект на курсе, трек трансформеров: DistilBERT дообучается отличать хорошие отзывы IMDB от плохих. Студенты собирают класс ModelTrainer, одиннадцать методов: загрузка данных, обучение, валидация, метрики, логирование. Есть там и save_model, десятая часть балла за проект. Всё условие умещается в докстринг: "Saves model to dst_path". Плюс одно предупреждение: проверьте, не обёрнута ли модель в DataParallel.
В 41% проектов метод закрыт одной строчкой: torch.save(model.state_dict()). По букве не придерёшься: модель сохранена в dst_path, файл на диске лежит, галочка стоит. Через месяц файл открывают. Модели там нет.
Файл есть. Чего нет:
1️⃣ Архитектуры
В state_dict только веса, голый словарь тензоров: ни конфига, ни описания слоёв. Загрузить его можно лишь в модель, заново собранную руками ровно той же архитектуры, иначе загрузка не сойдётся по слоям.
2️⃣ Токенизатора
Модель принимает индексы токенов, а не текст. Токенизатор рядом не сохранён, значит текст не во что превращать: инференс не собрать вовсе. Причём нужен тот же самый: у другого соответствие "слово → номер" своё.
Ирония: единственное, о чём условие предупредило прямым текстом, сделали почти все — обёртку развернули. Почти: в одной работе проверка на DataParallel написана, а строка внутри неё ничего не присваивает. Галочка снова стоит, эффекта снова ноль. Сломались не там, где условие предупреждало, а там, где оно промолчало.
Полезные привычки ML'щика
Сохраняйте модель перезагружаемой. model.save_pretrained(path), из-под обёртки — model.module.save_pretrained(path), и рядом в ту же папку tokenizer.save_pretrained(path). Тогда один from_pretrained(path) поднимает всё разом: конфиг, архитектуру, веса, токенизатор, на любой машине. Проверить легко: сохраните чекпойнт, перезапустите сессию и поднимите модель заново с диска — from_pretrained(path). Прогоните несколько примеров через инференс: предсказания должны совпасть с теми, что модель выдавала до сохранения. Совпали — сохранилась модель, а не файл.
Сохранить файл и сохранить модель — разные вещи. Первое закрывает букву условия, второе — смысл. А прод экзаменует без докстринга: предупреждений не пишет, подсказок не даёт, вопрос у него один. Загрузится?
Ставить такие привычки проще на практике: здесь модель считается сохранённой, только когда поднялась на чужой машине.
BigData Team: the way you learn best