当 AI 训练、推理和数据处理开始争夺同一批 GPU,算力就不再只是采购问题,也变成了资源分配问题。谁能获得资源、等待多久、为此支付多少成本,都会影响个人、团队乃至组织参与技术创新的机会。讨论“资源、社会公平与算力”,真正值得工程师追问的是:公平能否从抽象原则变成可检查、可执行的系统规则?
算力分配不只有吞吐量
传统调度器通常优化利用率、吞吐量或任务完成时间。这些指标很重要,但它们没有回答资源应该优先服务谁。
例如,一支拥有大量预算的团队可以持续提交长时间 GPU 任务。如果系统只采用先到先得策略,小团队的短任务可能长期排队;如果完全按照价格竞价,资金优势又会直接转化为算力优势。两种策略都很容易实现,却未必符合组织希望维护的公平边界。
工程上可以把公平拆成几个可测量的问题:
- 每个团队获得的 GPU 时长是否与约定份额一致?
- 小任务和交互式实验是否存在最大等待时间?
- 是否为教学、公益研究或低预算项目保留基础额度?
- 高优先级任务能否抢占资源,谁有权设置优先级?
- 配额、排队时间和拒绝原因是否对使用者透明?
这些问题不能只靠一句“使用公平调度”解决。配额控制的是上限,优先级决定排队次序,抢占机制处理资源冲突,审计日志则负责解释结果。它们需要组合使用。
从平均分配转向可解释分配
平均分配看似公平,但不同任务的需求并不相同。一次课程实验可能只需要一张 GPU 和两个小时,模型训练则可能连续占用八张 GPU 数天。简单地给每个团队相同数量的设备,可能造成一边闲置、一边拥堵。
更实用的办法是建立“基础保障加弹性借用”模型:每个租户拥有最低保障额度;空闲算力可以被其他租户借用;当原租户需要资源时,系统通过排队或抢占逐步收回。这样既避免资源静置,也不会让长期高负载用户永久占据公共资源。
但权重本身也是政策。团队人数、历史使用量、项目价值和付费水平都可以成为权重来源,而每一种选择都会产生不同结果。因此,调度规则至少应具备版本记录、审批流程和定期复核,而不是作为一组无人解释的配置长期运行。
可以这样实践:模拟加权公平分配
下面的 Python 程序演示一种简化的加权分配方法。它先满足各团队的基础保障,再按照权重逐个分配剩余 GPU,同时不超过团队申报的需求。
运行前只需要安装 Python 3;可以修改 TOTAL_GPUS 和 TEAMS,观察不同配额与权重如何改变结果。
from dataclasses import dataclass
@dataclass
class Team:
name: str
demand: int
guaranteed: int
weight: int
allocated: int = 0
TOTAL_GPUS = 16
TEAMS = [
Team("teaching", demand=6, guaranteed=3, weight=3),
Team("research", demand=12, guaranteed=4, weight=2),
Team("commercial", demand=16, guaranteed=2, weight=1),
]
def allocate(total: int, teams: list[Team]) -> None:
# 先发放基础保障,但不超过实际需求。
for team in teams:
grant = min(team.demand, team.guaranteed, total)
team.allocated += grant
total -= grant
# 按权重轮转分配剩余资源,直到资源或需求耗尽。
while total > 0:
progressed = False
for team in teams:
for _ in range(team.weight):
if total == 0:
break
if team.allocated < team.demand:
team.allocated += 1
total -= 1
progressed = True
if not progressed:
break
allocate(TOTAL_GPUS, TEAMS)
for team in TEAMS:
print(
f"{team.name:12} demand={team.demand:2} "
f"allocated={team.allocated:2} "
f"satisfaction={team.allocated / team.demand:.0%}"
)
这段代码适合讨论规则,不适合直接充当生产调度器。真实系统还必须处理任务时长、GPU 型号、显存容量、节点拓扑、抢占成本和恶意申报等问题。更重要的是,应同时记录“请求了多少”“等待了多久”和“为什么没有得到资源”,否则只能看到分配结果,无法判断过程是否公平。
如果使用 Kubernetes,可以这样实践:先用命名空间配额建立硬边界。下面假设集群中的 GPU 资源名为 nvidia.com/gpu,实际名称应按设备插件调整。
apiVersion: v1
kind: ResourceQuota
metadata:
name: gpu-quota
namespace: teaching
spec:
hard:
requests.nvidia.com/gpu: "4"
limits.nvidia.com/gpu: "4"
count/pods: "20"
应用并检查配额:
kubectl apply -f gpu-quota.yaml
kubectl describe resourcequota gpu-quota -n teaching
kubectl get pods -n teaching --sort-by=.metadata.creationTimestamp
ResourceQuota 只能限制资源总量,不能单独保证等待时间或实现跨团队加权公平。生产环境通常还需要队列、优先级、准入控制以及可观测性组件协同工作。
落地前检查这五件事
算力公平不是让所有人得到完全相同的资源,而是让差异化分配拥有公开理由、明确下限和申诉空间。落地时可以检查以下事项:
- 定义目标:明确系统优化的是利用率、等待时间、最低保障,还是几者之间的平衡。
- 公布规则:让用户知道配额、优先级、抢占条件和预计等待时间。
- 保留审计:记录请求、分配、拒绝、抢占和规则版本。
- 防止固化:定期检查权重是否让既有优势不断累积。
- 小范围试运行:先在一个队列或命名空间验证,再扩大影响范围。
算力越稀缺,默认规则的影响就越大。工程团队不可能用调度算法解决全部社会问题,但可以避免把未经讨论的价值判断隐藏在队列、价格和配置文件里。