Hugging Face против AI Gitee: битва платформ для дата-саентистов

41bc4df48bda52dd5c69a199a553c1bd.png

Привет, жители Хабра! Сегодня поговорим об интересном феномене в мире машинного обучения: противостоянии Hugging Face и его китайского аналога AI Gitee. Как это часто бывает с инструментами машинного обучения, тут не все так однозначно. Разберем установку Hugging Face на разные системы, что скрывается за фасадом HuggingFace, что AI Gitee использует вместо Git LFS, неочевидные проблемы при интеграции и мониторинг работы моделей в продакшене. Начнем!

Кто есть кто

8272aee4e06be21a83f98744c86a5c38.png

Hugging Face — это сегодня, по сути, стандарт де-факто для работы с нейросетями. Это не просто «GitHub для ML-моделей», а целая экосистема, построенная вокруг машинного обучения и особенно трансформеров. В ее основе лежит огромный хаб с открытыми моделями и датасетами для самых разных задач: от простой классификации текста до мультимодальных монстров типа Stable Diffusion.

Особняком стоит Spaces — платформа, где можно не только посмотреть бесплатные демки моделей, но и захостить свою, причем при желании прямо с GPU (конечно, уже не бесплатно). Для разработчиков тут целый набор инструментов: мощная библиотека Transformers для инференса моделей, Gradio для быстрого создания веб-интерфейсов буквально за пару строк кода, продуманное API для интеграции всего этого добра в продакшен. В последние годы платформа стала настолько популярной, что даже крупные компании вроде Meta и Google выкладывают там свои модели.

AI Gitee — это ML-направление более широкой платформы Gitee, которая создавалась как китайский аналог GitHub. Проект развивается при поддержке крупной китайской компании OSCHINA и включает в себя не только хостинг кода, но и специализированные инструменты для работы с нейросетями. В отличие от HuggingFace, здесь ML — только одно из направлений, хотя и активно развивающееся. Платформа особенно интересна своей коллекцией моделей и инструментов, заточенных под китайский язык и локальное железо вроде процессоров Loongson. Есть своя система дистрибуции моделей, свои инструменты оптимизации и специфичные решения для работы через китайские сети. Правда, экосистема более закрытая: документация преимущественно на китайском, а сообщество разработчиков сконцентрировано внутри страны.

Установка — первый камень преткновения

68411964e9e226aff62bc1ebb5cb618e.png

Для начала разберемся с тем, о чем обычно молчат туториалы, — с установкой Hugging Face на разные системы. На Arch Linux процесс выглядит так.

Для начала скачаем pip — по умолчанию в Арче его нет. Создаем виртуальное окружение. Арч заботится о том, чтобы пользователь не поломал всю систему, где используются питоновские библиотеки, и хочет, чтобы все, что ставится в обход его базового пакетного менеджера pacman, было изолировано. Заодно заранее скачаем базовые необходимые для запуска нейросетей библиотеки:

sudo pacman -S python python-pip
python -m venv huggingface-env source huggingface-env/bin/activate
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
pip install transformers bitsandbytes

Дальше скачаем и установим huggingface-cli, с помощью которого мы подключимся к нашему аккаунту HuggingFace. Через API сможем скачивать оттуда необходимые нам модели:

pip install huggingface_hub
huggingface-cli login

Вас попросят вставить токен доступа. Получить токен можно так:

  • Зайдите в ваш профиль на сайте Hugging Face.

  • Перейдите в раздел SettingsAccess Tokens.

  • Создайте новый токен, указав нужные права доступа (обычно достаточно read).

  • Скопируйте токен и вставьте его в терминал.

HuggingFace: что скрывается за фасадом

2b953a8c5f5eb3e8b4c6181c78508b11.png

В официальных источниках HuggingFace представляют как платформу для работы с моделями машинного обучения. На деле это гораздо более сложная и многогранная система. Возьмем, к примеру, систему версионирования моделей. HuggingFace использует Git LFS, что позволяет эффективно хранить и передавать большие файлы весов моделей. Но при работе с большими моделями в продакшне вы неизбежно столкнетесь с проблемами кэширования и оптимизации загрузки.

К слову про GitLFS. Репозиториии с нейросетями обычно весят немало: веса моделей могут легко переваливать за несколько десятков гигабайт. Так что активируем LFS сразу в нашем проекте:

sudo pacman -S git-lfs # скачиваем LFS через пакетный менеджер
git lfs install # активируем

Система кэширования в HuggingFace реализована через сложную систему промежуточных файлов и метаданных. При первой загрузке модели создается локальный кэш, который хранит не только веса, но и конфигурации, токенизаторы и метаданные. Это удобно для разработки, но в production-окружении может привести к неожиданным проблемам с диском:

from transformers import AutoModel
model = AutoModel.from_pretrained("bert-base-uncased")
# На этом этапе HuggingFace создает кэш в ~/.cache/huggingface/
# И если у вас несколько окружений или контейнеров, кэш начинает
# размножаться, как кролики

Отдельного упоминания заслуживает механизм квантизации моделей. HuggingFace предоставляет несколько уровней оптимизации, от простого перевода в fp16 до сложных схем квантизации:

from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased")
model.half()  # Простая fp16 квантизация

# Более сложная схема с динамической квантизацией
from torch.quantization import quantize_dynamic
quantized_model = quantize_dynamic(
    model, {torch.nn.Linear}, dtype=torch.qint8
)

AI Gitee: другая сторона Великой стены

58dd85864242f537b6fed9b40600a61d.png

AI Gitee подходит к решению тех же проблем совершенно иначе. Вместо Git LFS здесь используется собственный протокол синхронизации, оптимизированный под китайские сети. Это дает более высокую скорость загрузки внутри Китая, но создает проблемы при работе из других регионов.

Система управления моделями в AI Gitee построена вокруг концепции централизованного регистра:

from aigitee import ModelRegistry, Config

# Создание конфигурации с учетом локальной специфики:
config = Config(
    model_path="bert-base-chinese",
    quantization="int8",  # Принудительная квантизация для экономии памяти
    network_timeout=30  # Увеличенный таймаут для работы через VPN
)

model = ModelRegistry.load(config)

Особенно интересно сравнить подходы к оптимизации inference. Если HuggingFace делает ставку на универсальность и поддержку различных бэкендов, то AI Gitee фокусируется на оптимизации под конкретные китайские процессоры:

# HuggingFace: универсальный подход
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
    "gpt2",
    device_map="auto",  # Автоматическое распределение по доступным устройствам
    torch_dtype=torch.float16
)

# AI Gitee: специфичная оптимизация
from aigitee.optimizers import LoongsonOptimizer
model = LoongsonOptimizer.optimize(model, target_arch="3A5000")

Архитектурные особенности в продакшене

a24f00f1b1474be1141a4bbb9d378edf.png

При переходе в продуктовую среду различия между платформами становятся еще более заметными. HuggingFace следует микросервисной архитектуре, где каждый компонент может работать независимо. Это дает гибкость при масштабировании, но усложняет отладку и мониторинг.

В реальных проектах это выливается в необходимость создания дополнительных слоев абстракции. Например, типичный сервис на базе HuggingFace в продакшене может выглядеть так:

class ModelService:
    def __init__(self):
        self.model_lock = asyncio.Lock()
        self.model_cache = {}
        
    async def get_model(self, model_name: str):
        async with self.model_lock:
            if model_name not in self.model_cache:
                # Загрузка модели с автоматическим восстановлением
                try:
                    model = await self._load_model(model_name)
                except Exception as e:
                    logger.error(f"Failed to load model {model_name}: {e}")
                    raise
                
                self.model_cache[model_name] = model
            return self.model_cache[model_name]
    
    async def _load_model(self, model_name: str):
        # Здесь начинается самое интересное...
        return model

AI Gitee, напротив, использует монолитную архитектуру. Все компоненты тесно связаны между собой — это упрощает развертывание, но создает проблемы при необходимости горизонтального масштабирования.

Производительность: цифры и реальность

24d7918240394ed2aa20cd28c3fc3f9f.png

В синтетических тестах обе платформы показывают схожие результаты при работе с базовыми моделями. Но при увеличении нагрузки начинают проявляться существенные различия. HuggingFace лучше справляется с параллельной обработкой запросов благодаря более продвинутой системе батчинга:

# HuggingFace: эффективный батчинг
inputs = tokenizer(["text1", "text2", "text3"], padding=True, return_tensors="pt")
outputs = model(**inputs)  # Автоматическая обработка батча

# AI Gitee: требуется ручная оптимизация
batch = AIGiteeBatch()
for text in ["text1", "text2", "text3"]:
    batch.add(tokenizer.encode(text))
outputs = model.batch_inference(batch)

Отдельного внимания заслуживает работа с памятью. HuggingFace предоставляет механизмы для оптимизации использования GPU памяти через gradient checkpointing и модели с низкой точностью:

from transformers import AutoModelForSequenceClassification
import torch

model = AutoModelForSequenceClassification.from_pretrained(
    "bert-large-uncased",
    torch_dtype=torch.float16,
    gradient_checkpointing=True,
    device_map="auto"
)

# В реальности же часто приходится идти дальше
model.config.use_cache = False  # Отключаем кэш key/value для экономии памяти
torch.cuda.empty_cache()  # Явная очистка GPU памяти
AI Gitee подходит к этому вопросу иначе, предоставляя встроенные механизмы для работы с ограниченными ресурсами:
from aigitee.optimization import MemoryOptimizer

config = MemoryOptimizer.create_config(
    max_gpu_memory="8GiB",
    enable_cpu_offload=True,
    quantization_scheme="dynamic_int8"
)

model = ModelRegistry.load("chinese-bert-wwm", config=config)

Подводные камни интеграции

caa9df9c983a3d57f3d53dcf814a03dc.png

При интеграции этих платформ в существующую инфраструктуру возникает ряд неочевидных проблем. Например, HuggingFace по умолчанию использует глобальный кэш моделей, что может создавать конфликты в многопользовательской среде:

import os
from pathlib import Path

# Установка отдельного кэша для каждого окружения
os.environ['TRANSFORMERS_CACHE'] = str(Path('/path/to/project/.cache/huggingface'))
os.environ['HF_HOME'] = str(Path('/path/to/project/.cache/huggingface'))

# Но даже это не спасает от проблем с правами доступа
# и конкурентными обновлениями кэша
AI Gitee имеет свои особенности, связанные с аутентификацией и работой через прокси:

from aigitee.auth import Credentials
from aigitee.network import ProxyConfig

proxy_config = ProxyConfig(
    http_proxy="http://proxy.corporate:8080",
    https_proxy="http://proxy.corporate:8080",
    verify_ssl=False  # Иногда приходится отключать проверку SSL
)

credentials = Credentials.from_env()  # Загрузка креденшлов из переменных окружения
ModelRegistry.configure(proxy_config, credentials)

Мониторинг и отладка

f97f07052aaf547e797ac6349206d9de.png

Отдельная головная боль — мониторинг работы моделей в продакшене. HuggingFace предоставляет базовые метрики через стандартный API, но для серьезного мониторинга приходится изобретать собственные решения:

from prometheus_client import Counter, Histogram
import time

inference_latency = Histogram(
    'model_inference_latency_seconds',
    'Model inference latency',
    ['model_name', 'quantization']
)
inference_errors = Counter(
    'model_inference_errors_total',
    'Total number of inference errors',
    ['model_name', 'error_type']
)

class MonitoredModel:
    def __init__(self, model_name: str):
        self.model_name = model_name
        self.model = self._load_model()
        
    @inference_latency.labels(model_name='bert', quantization='fp16').time()
    def predict(self, input_text: str):
        try:
            return self.model(input_text)
        except Exception as e:
            inference_errors.labels(
                model_name='bert',
                error_type=type(e).__name__
            ).inc()
            raise

Подводим итоги

После года работы с обеими платформами в продакшне можно сказать, что выбор между HuggingFace и AI Gitee не так однозначен, как может показаться на первый взгляд. HuggingFace предоставляет более зрелую экосистему и лучшую документацию, но AI Gitee может быть более эффективным для специфических задач — особенно при работе с китайским языком.

А каков ваш опыт работы с этими платформами? Особенно интересно услышать про нестандартные сценарии использования и решения проблем производительности.

© Habrahabr.ru