Hugging Face 的 TensorFlow 哲学
Hugging Face 采用了 “Keras 优先” 的 TensorFlow 哲学,将 Keras 视为主要的高级 API,而不是需要绕过的障碍。这种方法确保 transformer 模型能够完全兼容标准的 Keras 工作流,包括 fit()、compile() 和 predict(),同时利用 XLA 实现与 JAX 和 PyTorch 相当的性能。
与 Keras 的深度集成
transformers 库中的所有 TensorFlow 模型和层都实现为 Keras Model 和 Layer 对象。此设计使用户能够使用标准的 Keras 方法进行训练和推理,而无需编写低层次的训练循环。
模型组合与灵活性
Keras 子类化使得创建混合模型成为可能。用户可以将多个预训练模型——例如将语言模型与视觉 transformer 合并——组合成一个 Keras 模型。这既能开发复杂的架构,又保持了高级 API 的优势。
自动化损失函数
为简化训练过程,Hugging Face 提供了与基础模型和输出类型匹配的默认损失函数。如果用户在调用 compile() 时未提供 loss 参数,库会自动提供一个能够正确处理填充和掩码的损失函数(例如针对 BERT 的掩码语言建模损失)。用户可以通过在 compile() 中指定自定义 loss,或在子类化模型中实现自己的 train_step() 来覆盖此行为。
标准化标签处理
标签现在使用标准的 Keras 约定传递(作为单独的参数或作为 (inputs, labels) 元组的一部分),而不再包含在输入字典中。此更改确保了与标准 Keras 指标的兼容性,并减少了用户的困惑。
数据管道优化
为避免将整个已分词数据集加载到内存中产生的内存开销,Hugging Face 将 datasets 库与 tf.data 集成。
使用 prepare_tf_dataset() 的高效流式处理
虽然小型数据集可以转换为 NumPy 数组,但大型数据集受益于 prepare_tf_dataset() 方法。该方法将数据集包装为 tf.data.Dataset 对象,从而实现:
- 即时加载:数据从磁盘流式读取,而不是一次性加载到内存。
- 动态填充:填充在批次上进行,而不是对整个数据集进行,从而减少填充标记的数量并提升训练速度。
- 自动过滤:模型会自动过滤掉对特定架构无效的输入列。
性能与部署
XLA 加速
Hugging Face 使用 XLA(Accelerated Linear Algebra),这是一种 TensorFlow 与 JAX 共享的即时编译器,用于优化线性代数代码,以实现更快的执行和更低的内存使用。
关键的性能提升包括:
- 生成速度:使用 XLA 更新的
generate()代码使文本生成速度快于 PyTorch,且可与 JAX 相媲美。 - 训练速度:TF 模型在语言模型训练等任务上已达到接近 JAX 的速度。
XLA 的一个限制是需要静态输入形状;可变的序列长度可能导致重复重新编译,从而抵消性能收益。
端到端部署
为简化通过 TF Serving 和 TFX 的部署,Hugging Face 正在将分词过程直接嵌入模型产物中。这消除了推理时对外部分词器库的依赖。对于诸如 BERT 等常见模型,用户可以通过将分词器和模型包装成单个 Keras Model 来创建 EndToEndModel,使模型能够接受原始字符串作为输入。
社区与模型共享
可以使用 push_to_hub() 将模型上传至 Hugging Face Hub,这会创建模型页面和自动生成的模型卡。这样,微调模型即可使用与基础模型相同的 API,促进共享产物和实践的开放生态系统。