Add extra files
./code/extra-files/test.py
1#!/usr/bin/env python3
2
3import torch
4import numpy as np
5
6
7class Foo(torch.nn.Module):
8 def __init__(self):
9 super().__init__()
10 self.x = torch.nn.Parameter(torch.tensor([2.5]))
11
12 def forward(self, y: torch.Tensor):
13 return self.x + y
14
15
16@torch.inference_mode()
17def main():
18 f = Foo()
19 print(f(torch.tensor([3.5, 2.0])))
20
21 mean = np.array([1.5, 2.25, -3.8], dtype=np.float32)
22 inv_std = np.array([2.5, 225, 380], dtype=np.float32)
23
24 extra_files = dict()
25 extra_files["window_size"] = "20"
26 extra_files["window_shift"] = "64"
27 extra_files["cmvn_dim"] = f"{mean.shape[0]}"
28 extra_files["cmvn_mean"] = mean.tobytes()
29 extra_files["cmvn_inv_std"] = inv_std.tobytes()
30
31 m = torch.jit.script(f)
32 m.save("m.pt", _extra_files=extra_files)
33
34 saved = dict()
35 saved["window_size"] = ""
36 saved["window_shift"] = ""
37
38 saved["cmvn_dim"] = ""
39 saved["cmvn_mean"] = ""
40 saved["cmvn_inv_std"] = ""
41
42 m2 = torch.jit.load("m.pt", _extra_files=saved)
43 saved["cmvn_mean"] = np.frombuffer(saved["cmvn_mean"], dtype=np.float32)
44 saved["cmvn_inv_std"] = np.frombuffer(saved["cmvn_inv_std"], dtype=np.float32)
45 print(saved)
46 print(type(saved["window_shift"])) # <class 'bytes'>
47
48
49"""
50tensor([6.0000, 4.5000])
51{'window_size': b'20', 'window_shift': b'64', 'cmvn_dim': b'3', 'cmvn_mean': array([ 1.5 , 2.25, -3.8 ], dtype=float32), 'cmvn_inv_std': array([ 2.5, 225. , 380. ], dtype=float32)}
52<class 'bytes'>
53"""
54
55
56if __name__ == "__main__":
57 main()
./code/extra-files/main.cc
1#include "torch/script.h"
2
3std::vector<float> ToFloat(const std::string &s) {
4 const float *p = reinterpret_cast<const float *>(s.data());
5 int32_t n = s.size() / 4;
6
7 // assume little endian
8 return {p, p + n};
9}
10
11int main() {
12 // see torch/csrc/jit/module.h
13 // see
14 // https://github.com/pytorch/pytorch/blob/main/test/cpp/jit/test_save_load.cpp#L76
15 torch::jit::ExtraFilesMap extra_files{{"window_size", ""},
16 {"cmvn_mean", ""},
17 {"cmvn_inv_std", ""},
18 {"cmvn_dim", ""}};
19 torch::jit::Module m = torch::jit::load("./m.pt", torch::kCPU, extra_files);
20
21 int32_t dim = atoi(extra_files["cmvn_dim"].c_str());
22 if (dim != extra_files["cmvn_mean"].size() / 4 ||
23 dim != extra_files["cmvn_inv_std"].size() / 4) {
24 std::cout << "corrupted data!\n";
25 return -1;
26 }
27
28 auto cmvn_mean = ToFloat(extra_files["cmvn_mean"]);
29 auto cmvn_inv_std = ToFloat(extra_files["cmvn_inv_std"]);
30 int32_t window_size = atoi(extra_files["window_size"].c_str());
31 std::cout << "int window size: " << window_size << "\n";
32
33 for (const auto &p : extra_files) {
34 std::cout << p.first << ": " << p.second << "\n";
35 }
36 std::cout << "cmvn_mean: ";
37 for (auto f : cmvn_mean) {
38 std::cout << f << " ";
39 }
40 std::cout << "\n";
41
42 std::cout << "cmvn_inv_std: ";
43 for (auto f : cmvn_inv_std) {
44 std::cout << f << " ";
45 }
46 std::cout << "\n";
47
48 std::cout << "is training: " << m.is_training() << "\n";
49 m.eval();
50 std::cout << "after m.eval(): is training: " << m.is_training() << "\n";
51 torch::Tensor x = torch::tensor({1, 2, 3}, torch::kFloat);
52 torch::Tensor y = m.run_method("forward", x).toTensor();
53 std::cout << y << "\n";
54
55 return 0;
56}
57/*
58int window size: 20
59cmvn_inv_std: @aCC
60cmvn_mean: ?@33s
61cmvn_dim: 3
62window_size: 20
63cmvn_mean: 1.5 2.25 -3.8
64cmvn_inv_std: 2.5 225 380
65is training: 1
66after m.eval(): is training: 0
67 3.5000
68 4.5000
69 5.5000
70[ CPUFloatType{3} ]
71 */