Python 现代开发学习笔记

(十六)组织一份完整模型版本

models/
├── current.json              保存下次默认加载的版本名
└── v1/
    ├── weights.pt            PyTorch state_dict
    ├── preprocess.npz        x/y 的训练均值与标准差
    ├── metadata.json         特征顺序、结构、数据摘要与版本
    ├── metrics.json          验证选中轮数与评估结果
    ├── history.json          每轮训练和验证损失
    ├── splits.json           原始数据的三组下标
    └── manifest.json         前六个文件各自的 SHA-256

preprocess.npz 回到第十一章的数组文件格式,保存四个具名数组。metadata.json 中的 architecture="linear-2-1" 与 FEATURES 使加载代码能先核对解释方式;CSV 摘要和保存的下标帮助复查实验来源。

# 项目文件:model_project/src/modeldelivery/releases.py
import hashlib
import json
import os
from pathlib import Path
import re
from tempfile import TemporaryDirectory

import numpy as np
import torch

from .data import FEATURES, prepare
from .training import fit

FILES = {
    "weights.pt",
    "preprocess.npz",
    "metadata.json",
    "metrics.json",
    "history.json",
    "splits.json",
}


def version_path(root, version):
    if not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]{0,63}", version):
        raise ValueError("版本名请使用字母数字开头的简短名称")
    return Path(root).resolve() / version


def write_json(path, value):
    path.write_text(json.dumps(value, ensure_ascii=False, indent=2), encoding="utf-8")


def verify(folder):
    # 先检查完整清单,再逐个比较文件字节的摘要。
    folder = Path(folder)
    manifest = json.loads((folder / "manifest.json").read_text(encoding="utf-8"))
    if manifest.get("format") != 1 or set(manifest["files"]) != FILES:
        raise ValueError("模型交付目录的文件清单不完整")
    for name, expected in manifest["files"].items():
        if hashlib.sha256((folder / name).read_bytes()).hexdigest() != expected:
            raise ValueError(f"模型文件摘要不一致:{name}")
    return manifest

verify() 要求清单列出六个配套文件,再逐个计算摘要。复制过程中少了一个文件或某个字节发生变化,装载前就会发现。摘要用于检查文件完整性;模型目录的来源仍由发布和传输过程确定。

权重、缩放与说明先形成六个文件,再计算清单摘要,装载前逐项重算比较

笔记正文与全部题解 · Ctrl / ⌘ K