ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Optuna Artifacts 模块实战指南:用统一的 ArtifactStore 接口管理本地与云上大文件数据

Optuna Artifacts 模块实战指南:用统一的 ArtifactStore 接口管理本地与云上大文件数据 Optuna Artifacts 模块实战指南用统一的 ArtifactStore 接口管理本地与云上大文件数据【免费下载链接】optunaA hyperparameter optimization framework项目地址: https://gitcode.com/GitHub_Trending/op/optuna本文基于 Optuna 官方参考文档 docs/source/reference/artifacts.rst 展开完整讲解optuna.artifacts模块的三大类 ArtifactStore本地文件系统、AWS S3 兼容对象存储、GCS、四个核心 APIupload_artifact、get_all_artifact_meta、download_artifact、ArtifactMeta以及Backoff重试中间件的参数与底层实现机制。读完本文你能够把超参搜索过程中产生的模型快照、结构文件等大体积数据从 RDB 中剥离出来透明地存放到本地或远端存储并在优化结束后按 trial 精确找回。模块定位为什么需要 optuna.artifactsOptuna 的优化历史参数、目标值、时间戳等通过 storage 对象持久化到 SQLite、MySQL 等数据库中trial.set_user_attr也可以记录一些实验属性但这些字段适合存放整数、短字符串等小数据。当每个 trial 需要保存的是几十 MB 的模型权重、化学结构文件或生成式模型的输出图像时直接写入 RDB 既不适合也不高效。optuna.artifacts模块就是为这类“大文件数据”设计的artifact产物文件与某个Trial或Study关联元数据记入数据库文件本体则存放到可插拔的 artifact 后端。文档中给出的后端支持矩阵如下引自 docs/source/reference/artifacts.rst类名支持的存储FileSystemArtifactStore本地文件系统、网络文件系统NFSBoto3ArtifactStoreAWS S3 兼容对象存储GCSArtifactStoreGoogle Cloud Storage模块内还有两条官方注意事项值得原样继承各ArtifactStore类定义的方法open_reader/write/remove不面向库用户直接调用它们是实现该协议的内部接口用户应使用upload_artifact等顶层函数ArtifactStore目前没有提供正式的 artifact 删除 API如需批量清理文档指向 FAQ 中的 remove_for_artifact_store 一节给出“hack”方案本文后文会完整给出。在包结构中optuna.artifacts通过惰性导入挂载到optuna顶层见 optuna/init.py 中的artifacts _LazyImport(optuna.artifacts)因此可以在拿到一个 study 或 trial 后直接import optuna; optuna.artifacts.upload_artifact(...)使用。统一抽象ArtifactStore 协议所有后端都实现同一个鸭子类型协议定义在 optuna/artifacts/_protocol.pyclass ArtifactStore(Protocol): def open_reader(self, artifact_id: str) - BinaryIO: ... def write(self, artifact_id: str, content_body: BinaryIO) - None: ... def remove(self, artifact_id: str) - None: ...open_reader(artifact_id)返回一个以二进制读模式打开的文件对象类似open(..., rb)不存在时应抛出ArtifactNotFoundwrite(artifact_id, content_body)把内容写入后端remove(artifact_id)从后端删除该 artifact。各实现文件末尾都有 mypy 运行时断言如 optuna/artifacts/_filesystem.py 中的_: ArtifactStore FileSystemArtifactStore()用于保证每个后端都完整实现了协议的三个方法。异常类型ArtifactNotFound继承自OptunaError定义在 optuna/artifacts/exceptions.py。这一层抽象的直接收益是本地目录和远端 bucket 可以互换。本地单机优化时用FileSystemArtifactStore迁移到分布式 对象存储时只需替换 store 实例upload_artifact/download_artifact的调用代码不变。核心 API 详解optuna.artifacts导出的公共符号在 optuna/artifacts/init.py 中一览无余ArtifactMeta、FileSystemArtifactStore、Boto3ArtifactStore、GCSArtifactStore、Backoff、get_all_artifact_meta、upload_artifact、download_artifact。upload_artifact上传并登记 artifact实现位于 optuna/artifacts/_upload.py。函数签名全部为关键字参数def upload_artifact( *, artifact_store: ArtifactStore, file_path: str, study_or_trial: Trial | FrozenTrial | Study, storage: BaseStorage | None None, mimetype: str | None None, encoding: str | None None, ) - str:参数说明结合源码实现参数说明artifact_store目标存储后端实例file_path待上传文件的路径filename取其 basenamestudy_or_trialTrial、FrozenTrial或Studyartifact 将关联到该对象storage仅在study_or_trial为FrozenTrial时必填Trial/Study会自动从中取 storagemimetypeMIME 类型不指定时按文件扩展名猜测mimetypes.guess_type猜不到则回退为application/octet-streamencoding适合作为Content-Encoding头的编码如gzip不指定时同样按扩展名猜测返回值新生成的 artifact IDUUID4 字符串从源码看其工作流程是生成uuid4作为artifact_id→ 构造ArtifactMetaartifact_id、filename、mimetype、encoding四元组→ 以artifacts:artifact_id为键将元数据的 JSON 写入对应 trial 或 study 的system attributestorage.set_trial_system_attr/set_study_system_attr→ 最后以二进制读模式打开文件并调用artifact_store.write(artifact_id, f)把内容写入后端。也就是说“元数据进 RDB、内容进对象存储”这一职责拆分正是在此函数内完成的。另外注意一个版本兼容细节该函数通过convert_positional_args(previous_positional_arg_names[...], deprecated_version4.0.0, removed_version6.0.0)装饰旧版的位置参数调用方式自 4.0.0 起弃用、6.0.0 移除新代码请一律使用关键字传参。get_all_artifact_meta列出关联的 artifact 元信息实现位于 optuna/artifacts/_list_artifact_meta.pydef get_all_artifact_meta( study_or_trial: Trial | FrozenTrial | Study, *, storage: BaseStorage | None None ) - list[ArtifactMeta]:它读取对应 trial/study 的全部 system attrs筛选出以ARTIFACTS_ATTR_PREFIX artifacts:开头的键反序列化出ArtifactMeta列表返回。两个使用要点源码 docstring 原文强调传入Study时只返回直接上传到该 study 的 artifact不含其下各 trial 的 artifactOptuna 不会记录“当时用哪个 artifact store 上传的”因此重新下载时需要用户在代码侧自行管理 store 实例例如按约定重新构造同一个FileSystemArtifactStore/Boto3ArtifactStore。download_artifact按 ID 取回文件实现位于 optuna/artifacts/_download.pydef download_artifact(*, artifact_store: ArtifactStore, file_path: str, artifact_id: str) - None:行为细节若file_path已存在会直接抛FileExistsError避免覆盖已有文件随后调用artifact_store.open_reader(artifact_id)用shutil.copyfileobj流式落盘。artifact 不存在时由后端抛出ArtifactNotFound。ArtifactMeta四字段数据类dataclass class ArtifactMeta: artifact_id: str filename: str mimetype: str encoding: str | None它是get_all_artifact_meta的返回元素其中artifact_id是后续download_artifact的主键filename/mimetype/encoding用于在下载、展示时还原文件的原始名称与类型信息。三种 ArtifactStore 后端的参数与实现FileSystemArtifactStore本地/网络文件系统定义于 optuna/artifacts/_filesystem.py构造参数只有一个base_path: str | Path。基本用法源码 docstring 示例import os import optuna from optuna.artifacts import FileSystemArtifactStore from optuna.artifacts import upload_artifact base_path ./artifacts os.makedirs(base_path, exist_okTrue) artifact_store FileSystemArtifactStore(base_pathbase_path) def objective(trial: optuna.Trial) - float: ... trial.suggest_float(x, -10, 10) file_path generate_example(...) upload_artifact( artifact_storeartifact_store, file_pathfile_path, study_or_trialtrial, ) return ...实现上有两点值得注意write直接用open(filepath, wb)shutil.copyfileobj流式写入不经过整文件内存缓冲对大文件友好_get_filepath做了路径越界防护拒绝绝对路径artifact_id并用os.path.commonpath校验拼接后的路径仍落在base_path内防止通过../形式逃逸出基目录。Boto3ArtifactStoreAWS S3 兼容对象存储定义于 optuna/artifacts/_boto3.py构造参数参数说明bucket_name存放 artifact 的 bucket 名client可选复用一个已有的boto3S3 client缺省时内部boto3.client(s3)新建依赖环境变量中的凭证配置avoid_buf_copy可选默认False。为True时跳过“先把源文件对象拷贝到内存缓冲再上传”的步骤直接上传源对象avoid_buf_copy的来历Boto3 的upload_fileobj()可能会关闭传入的源文件对象上游 issue所以默认先shutil.copyfileobj到io.BytesIO再上传代价是多一份内存占用确认不需要该保护时可传avoid_buf_copyTrue省去一次缓冲拷贝。open_reader中若 S3 返回NoSuchKey或 HTTP 404会被统一转换为ArtifactNotFound见_is_not_found_error辅助函数保证跨后端的错误语义一致。import optuna from optuna.artifacts import Boto3ArtifactStore from optuna.artifacts import upload_artifact artifact_store Boto3ArtifactStore(my-bucket) def objective(trial: optuna.Trial) - float: ... trial.suggest_float(x, -10, 10) file_path generate_example(...) upload_artifact( artifact_storeartifact_store, file_pathfile_path, study_or_trialtrial, ) return ...GCSArtifactStoreGoogle Cloud Storage实验特性定义于 optuna/artifacts/_gcs.py带experimental_class(3.4.0)标记即自 3.4.0 起为实验性 API接口未来可能调整使用时需要留意。构造参数为bucket_name和可选的clientgoogle.cloud.storage.Client缺省新建需先完成如gcloud auth application-default login之类的凭证配置。实现上open_reader会download_as_bytes()后包一层BytesIO返回write则是content_body.read()后upload_from_string——也就是说 GCS 后端目前是整文件内存读写超大文件场景下这一点与 S3 后端的流式行为不同。Backoff指数退避重试中间件Backoff 是套在任意后端外面的中间件同样是ArtifactStore协议的一个实现构造参数与默认值参数默认值说明backend必填被包装的后端实例max_retries10最大尝试次数须大于 0multiplier2退避倍数须大于 0min_delay0.1首次重试前的基础等待秒数须大于 0max_delay30单次等待上限须大于min_delay按默认参数各次重试前的 sleep 依次为0.1, 0.2, 0.4, 0.8, 1.6, 3.2, 6.4, 12.8, 25.6, 30源码注释原样列出计算式是min(min_delay * multiplier**n, max_delay)。三个方法的重试语义一致ArtifactNotFound不重试、立即向上抛出“不存在”不是瞬时错误其他异常则记录 error 日志后退避重试最后一次仍失败才抛出write重试前会content_body.seek(0)把游标归零保证重传完整内容。组合示例源码 docstring 原文import optuna from optuna.artifacts import Boto3ArtifactStore from optuna.artifacts import Backoff from optuna.artifacts import upload_artifact artifact_store Backoff(Boto3ArtifactStore(my-bucket)) def objective(trial: optuna.Trial) - float: ... trial.suggest_float(x, -10, 10) file_path generate_example(...) upload_artifact( artifact_storeartifact_store, file_pathfile_path, study_or_trialtrial, ) return ...典型用法从上传到取回的完整闭环仓库内附带的教程脚本 tutorial/20_recipes/012_artifact_tutorial.py 给出了两种典型部署形态的最小可运行代码这里整理为可直接替换使用的骨架。场景一本地 SQLite 文件系统后端单机跑完整优化import os import optuna from optuna.artifacts import download_artifact from optuna.artifacts import FileSystemArtifactStore from optuna.artifacts import upload_artifact base_path ./artifacts os.makedirs(base_path, exist_okTrue) artifact_store FileSystemArtifactStore(base_pathbase_path) def objective(trial: optuna.Trial) - float: ... trial.suggest_float(x, -10, 10) file_path generate_example(...) # 生成一个文件 upload_artifact( artifact_storeartifact_store, file_pathfile_path, study_or_trialtrial, ) return ... study optuna.create_study(study_nametest_study, storagesqlite:///example.db) study.optimize(objective, n_trials100) # 取回最佳 trial 的全部 artifact download_artifact( artifact_storeartifact_store, file_path./best_artifact.out, artifact_id..., # 来自 upload_artifact 返回值或 get_all_artifact_meta )场景二远端 MySQL S3 后端分布式优化各 worker 的优化历史写 MySQL、artifact 写 S3两边并行读写互不干扰import boto3 import os import optuna from botocore.config import Config from optuna.artifacts import Boto3ArtifactStore from optuna.artifacts import upload_artifact artifact_store Boto3ArtifactStore( bucket_nameexample_bucket, clientboto3.client( s3, aws_access_key_idos.environ[AWS_ACCESS_KEY_ID], aws_secret_access_keyos.environ[AWS_SECRET_ACCESS_KEY], endpoint_urlos.environ[S3_ENDPOINT], configConfig(connect_timeout30, read_timeout30), ), ) def objective(trial: optuna.Trial) - float: ... trial.suggest_float(x, -10, 10) file_path generate_example(...) upload_artifact( artifact_storeartifact_store, file_pathfile_path, study_or_trialtrial, ) return ... study optuna.create_study( study_nametest_study, storagemysql://USER:PASSlocalhost:3306/test, # 按实际环境修改 ) study.optimize(objective, n_trials100)该教程中还给出了一个真实用例用 ASE 库做 CO 分子在 Pt 表面的吸附结构优化每个 trial 把优化后的结构序列化为 JSON 文件上传为 artifact优化结束后再download_artifact取回最佳结构并渲染为 PNG——完整实现可参考 tutorial/20_recipes/012_artifact_tutorial.py。“事后取回”的标准写法源码 docstring 示例import os import optuna from optuna.artifacts import download_artifact from optuna.artifacts import get_all_artifact_meta storage optuna.storages.get_storage(storage...) artifact_store ... # Optuna 不记录当时用了哪个 store需用户自行管理 study optuna.load_study(study_name..., storagestorage) best_trial study.best_trial artifact_metas get_all_artifact_meta(best_trial, storagestorage) download_dir ./best_trial_artifacts/ os.makedirs(download_dir, exist_okTrue) for meta in artifact_metas: download_artifact( artifact_storeartifact_store, artifact_idmeta.artifact_id, file_pathos.path.join(download_dir, meta.filename), )删除 artifact官方 FAQ 的清理方案如前所述ArtifactStore没有正式的对外删除 APIremove属于内部方法官方 FAQdocs/source/faq.rst 中remove_for_artifact_store一节的建议是首选为每个 study 创建独立的目录或 bucket清理时整体删除该目录/bucket 即可确实需要按脚本删除时可遍历 trial 的元数据调用内部removeFAQ 原文警告Study.add_trial与copy_study不会复制 artifact 文件删除时切勿误删源 study/trial 仍在引用的文件from optuna.artifacts import get_all_artifact_meta def remove_artifacts(study, artifact_store): storage study._storage for trial in study.trials: for artifact_meta in get_all_artifact_meta(trial, storagestorage): # 内部方法非正式 API artifact_store.remove(artifact_meta.artifact_id) for artifact_meta in get_all_artifact_meta(study): artifact_store.remove(artifact_meta.artifact_id)测试覆盖与源码导读optuna.artifacts的单元测试集中在 tests/artifacts_tests/按 API/后端一一对应测试文件覆盖对象test_upload_artifact.pyupload_artifact的元数据登记与内容写入test_download_artifact.pydownload_artifact的落盘与FileExistsError行为test_list_artifact_meta.pyget_all_artifact_meta的 trial/study 范围语义test_filesystem.pyFileSystemArtifactStoretest_boto3.pyBoto3ArtifactStore配合 mock 客户端test_gcs.pyGCSArtifactStoretest_backoff.pyBackoff重试与退避序列stubs.py测试用 stub 后端如果要在自定义场景下扩展后端正确路径是实现open_reader/write/remove三方法并遵循ArtifactNotFound语义可参考 optuna/artifacts/_protocol.py 的协议定义。小结与使用建议选型单机/共享文件系统用FileSystemArtifactStore注意它会做base_path越界校验多节点或云上环境用Boto3ArtifactStore任意 S3 兼容存储均可可用endpoint_url指向自建服务或实验性的GCSArtifactStore稳定性远端后端建议套一层Backoff其默认退避序列为 0.1s 起步、2 倍递增、30s 封顶、最多 10 次数据流记住“元数据ArtifactMeta进 RDB system attrs、文件本体进后端”这一分工——get_all_artifact_meta只能从数据库侧看到登记信息而 Optuna 不记录所用 store 的实例信息跨会话取回时需自行保持 store 配置一致清理优先“一 study 一目录/bucket”的物理隔离策略脚本级删除遵循 FAQ 给出的遍历get_all_artifact_meta 内部remove的方式并留意copy_study/add_trial不复制 artifact 文件的限制。【免费下载链接】optunaA hyperparameter optimization framework项目地址: https://gitcode.com/GitHub_Trending/op/optuna创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表