💾 Saving and Loading DSPy Programs: 永久保存你的智能程序

在使用 DSPy 优化和训练复杂的程序后,保存和加载这些程序是非常重要的一步。无论是为了后续的部署,还是为了在未来复用优化成果,DSPy 提供了灵活的保存和加载机制。本教程将带你了解如何保存和加载 DSPy 程序。


🗂️ 两种保存方式

DSPy 提供了两种主要的保存方式:

  1. 仅保存状态(State-only Saving)
    类似于 PyTorch 的权重保存,仅保存程序的内部状态(如签名、few-shot 示例、配置等),不包含程序的架构。
  2. 保存整个程序(Whole Program Saving)
    从 DSPy 2.6.0 开始支持,保存程序的架构和状态,便于直接加载完整程序。

⚙️ 状态保存(State-only Saving)

状态保存包括程序的内部状态,例如:

  • 签名(Signature)
  • few-shot 示例(Demos)
  • 配置(如 dspy.Predict 模块中使用的语言模型)

保存状态到 JSON 文件

以下是一个示例,展示如何保存程序的状态到 JSON 文件:

import dspy
from dspy.datasets.gsm8k import GSM8K, gsm8k_metric

# 配置语言模型
dspy.settings.configure(lm=dspy.LM("openai/gpt-4o-mini"))

# 加载数据集
gsm8k = GSM8K()
gsm8k_trainset = gsm8k.train[:10]

# 定义程序
dspy_program = dspy.ChainOfThought("question -> answer")

# 使用优化器编译程序
optimizer = dspy.BootstrapFewShot(
    metric=gsm8k_metric,
    max_bootstrapped_demos=4,
    max_labeled_demos=4,
    max_rounds=5
)
compiled_dspy_program = optimizer.compile(dspy_program, trainset=gsm8k_trainset)

# 保存状态到 JSON 文件
compiled_dspy_program.save("./dspy_program/program.json", save_program=False)

保存状态到 Pickle 文件

当程序中包含不可序列化的对象(如 dspy.Imagedatetime.datetime)时,可以选择保存为 Pickle 文件:

compiled_dspy_program.save("./dspy_program/program.pkl", save_program=False)

加载保存的状态

要加载保存的状态,需要重新创建相同的程序,然后使用 load 方法加载状态:

# 重新创建程序
loaded_dspy_program = dspy.ChainOfThought("question -> answer")

# 加载保存的状态
loaded_dspy_program.load("./dspy_program/program.json")

# 验证加载的状态
assert len(compiled_dspy_program.demos) == len(loaded_dspy_program.demos)
for original_demo, loaded_demo in zip(compiled_dspy_program.demos, loaded_dspy_program.demos):
    assert original_demo.toDict() == loaded_demo
assert str(compiled_dspy_program.signature) == str(loaded_dspy_program.signature)

如果是从 Pickle 文件加载:

loaded_dspy_program.load("./dspy_program/program.pkl")

🏗️ 保存整个程序(Whole Program Saving)

从 DSPy 2.6.0 开始,你可以保存整个程序,包括程序的架构和状态。这种方法使用了 cloudpickle 库,可以序列化和反序列化 Python 对象。

保存整个程序

将程序保存到一个目录中:

compiled_dspy_program.save("./dspy_program/", save_program=True)

加载整个程序

直接加载保存的程序,无需重新创建架构:

loaded_dspy_program = dspy.load("./dspy_program/")

# 验证加载的程序
assert len(compiled_dspy_program.demos) == len(loaded_dspy_program.demos)
for original_demo, loaded_demo in zip(compiled_dspy_program.demos, loaded_dspy_program.demos):
    assert original_demo.toDict() == loaded_demo
assert str(compiled_dspy_program.signature) == str(loaded_dspy_program.signature)

🔄 向后兼容性(Backward Compatibility)

  • DSPy < 2.7:保存的程序不保证向后兼容性。如果你使用 DSPy 2.5.35 保存程序,请确保加载时使用相同版本的 DSPy。
  • DSPy >= 2.7:在主要版本中保证向后兼容性,例如,使用 DSPy 2.7.0 保存的程序可以在 DSPy 2.7.10 中加载。

🎯 选择合适的保存方式

  • 如果你只需要保存程序的状态(如 few-shot 示例和配置),选择 状态保存
  • 如果你需要保存整个程序的架构和状态,便于直接加载和部署,选择 保存整个程序

通过保存和加载功能,DSPy 程序可以轻松地复用和部署。无论是简单的状态保存,还是完整的程序保存,DSPy 都为你的项目提供了灵活的解决方案。快试试吧!🎉

评论

发表回复

Only people in my network can comment.
人生梦想 - 关注前沿的计算机技术 acejoy.com 🐾 步子哥の博客

最近浏览