GPU-шеринг как у Яндекса, но на open source: Kueue
Яндекс недавно рассказал про Dev Cluster, и также в каналах подозрительно много выложили постов про это (например раз и два) — самописную систему шеринга GPU между ML-инженерами: бери карту, когда нужна, отдавай, когда нет, простаивающее железо достаётся другим. Решение классное, разработчики большие молодцы - но хотелось бы и у себя потрогать это руками, а не только позавидовать и восхититься.
Похожий механизм мы собрали в Kubeflow на ванильном Kubernetes + Kueue. Вот из каких сущностей это состоит:
ResourceFlavor — типы железа. Каждый flavor привязан к нодам через nodeLabels/tolerations: standart (CPU), a100-80g, a100-40g, h100, hgx-h100, плюс MIG-слайсы (`a100-80-10/20/40gb`, `h100-10/20/40gb`) — одна A100/H100 нарезается на куски, и слайс тоже квотируемый ресурс.
Cohort (иерархические) — основа шеринга. Корневой кохорт root, под ним кохорт каждой команды. Гарантии команды (nominalQuota) объявлены на её кохорте, и через общего родителя команды могут занимать (borrow) простаивающие ресурсы друг друга.
ClusterQueue — на команду генерим две очереди:
• regular — нулевая собственная квота, живёт заимствованием из кохорта. Может брать чужой простой сверх гарантий команды;
• prod — гарантированный кусок (`prodResources`), borrowWithinCohort: Never — ничего не занимает, зато reclaimWithinCohort: Any — мгновенно вытесняет чужие borrowed-джобы, когда ресурс нужен проду.
Это и есть аналог «отдавай, когда владелец вернулся»: исследовательская джоба бежит на чужих простаивающих GPU, но при появлении prod-нагрузки владельца её вытеснят и поставят обратно в очередь.
WorkloadPriorityClass (`prod-workload`, value 1000) — приоритет вытеснения внутри очереди: withinClusterQueue: LowerPriority.
LocalQueue — точка входа для пользователей: в каждом team/user namespace автоматически создаются default и prod (через namespace-configuration-operator), пользователь просто указывает имя очереди в джобе.
Topology (TAS) — topology-aware scheduling: обычные флейворы паком по zone/hostname, а для HGX H100 — по InfiniBand scalable unit, чтобы multi-node training не размазывало по фабрике.
Итого: гарантии командам + утилизация простоя + честное вытеснение — без собственного шедулера, декларативно, в GitOps на MAU 1000 клиентов.
Яндекс недавно рассказал про Dev Cluster, и также в каналах подозрительно много выложили постов про это (например раз и два) — самописную систему шеринга GPU между ML-инженерами: бери карту, когда нужна, отдавай, когда нет, простаивающее железо достаётся другим. Решение классное, разработчики большие молодцы - но хотелось бы и у себя потрогать это руками, а не только позавидовать и восхититься.
Похожий механизм мы собрали в Kubeflow на ванильном Kubernetes + Kueue. Вот из каких сущностей это состоит:
ResourceFlavor — типы железа. Каждый flavor привязан к нодам через nodeLabels/tolerations: standart (CPU), a100-80g, a100-40g, h100, hgx-h100, плюс MIG-слайсы (`a100-80-10/20/40gb`, `h100-10/20/40gb`) — одна A100/H100 нарезается на куски, и слайс тоже квотируемый ресурс.
Cohort (иерархические) — основа шеринга. Корневой кохорт root, под ним кохорт каждой команды. Гарантии команды (nominalQuota) объявлены на её кохорте, и через общего родителя команды могут занимать (borrow) простаивающие ресурсы друг друга.
ClusterQueue — на команду генерим две очереди:
• regular — нулевая собственная квота, живёт заимствованием из кохорта. Может брать чужой простой сверх гарантий команды;
• prod — гарантированный кусок (`prodResources`), borrowWithinCohort: Never — ничего не занимает, зато reclaimWithinCohort: Any — мгновенно вытесняет чужие borrowed-джобы, когда ресурс нужен проду.
Это и есть аналог «отдавай, когда владелец вернулся»: исследовательская джоба бежит на чужих простаивающих GPU, но при появлении prod-нагрузки владельца её вытеснят и поставят обратно в очередь.
WorkloadPriorityClass (`prod-workload`, value 1000) — приоритет вытеснения внутри очереди: withinClusterQueue: LowerPriority.
LocalQueue — точка входа для пользователей: в каждом team/user namespace автоматически создаются default и prod (через namespace-configuration-operator), пользователь просто указывает имя очереди в джобе.
Topology (TAS) — topology-aware scheduling: обычные флейворы паком по zone/hostname, а для HGX H100 — по InfiniBand scalable unit, чтобы multi-node training не размазывало по фабрике.
Итого: гарантии командам + утилизация простоя + честное вытеснение — без собственного шедулера, декларативно, в GitOps на MAU 1000 клиентов.