| 79 | }; |
| 80 | |
| 81 | struct BertModel::Impl { |
| 82 | explicit Impl(const std::string &filename, DLDeviceType device_type, |
| 83 | size_t n_layers, int64_t n_heads) |
| 84 | : device_type_(device_type) { |
| 85 | auto npz = cnpy::npz_load(filename); |
| 86 | NPZMapView root("", &npz); |
| 87 | |
| 88 | // HERE define your network model |
| 89 | embedding_ = LoadEmbedding(root.Sub("embeddings"), device_type); |
| 90 | |
| 91 | for (size_t i = 0; i < n_layers; ++i) { |
| 92 | auto view = root.Sub("encoder.layer." + std::to_string(i)); |
| 93 | NPZLoader params(view, device_type); |
| 94 | encoders_.emplace_back(std::move(params), n_heads); |
| 95 | } |
| 96 | |
| 97 | if (root.IsExist("pooler")) { |
| 98 | pooler_ = LoadPooler(root.Sub("pooler"), device_type); |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | // preprocess helper function |
| 103 | template <typename T> |
| 104 | void PadTensor(const std::vector<std::vector<T>> &data_array, int64_t n, |
| 105 | int64_t m, T pad_val, DLDeviceType device_type, |
| 106 | core::Tensor *output_tensor) { |
| 107 | if (m == 0 || n == 0 || data_array.size() == 0) { |
| 108 | return; |
| 109 | } |
| 110 | core::Tensor cpu_tensor(nullptr); |
| 111 | T *tensor_data_ptr; |
| 112 | if (device_type == DLDeviceType::kDLGPU) { |
| 113 | tensor_data_ptr = cpu_tensor.Reshape<T>({n, m}, DLDeviceType::kDLCPU, 0); |
| 114 | output_tensor->Reshape<T>({n, m}, device_type, 0); |
| 115 | } else { |
| 116 | tensor_data_ptr = output_tensor->Reshape<T>({n, m}, device_type, 0); |
| 117 | } |
| 118 | for (int64_t i = 0; i < n; ++i, tensor_data_ptr += m) { |
| 119 | auto &line = data_array[i]; |
| 120 | if (line.size() > 0) { |
| 121 | core::Copy(line.data(), line.size(), DLDeviceType::kDLCPU, |
| 122 | DLDeviceType::kDLCPU, tensor_data_ptr); |
| 123 | } |
| 124 | if (line.size() != static_cast<size_t>(m)) { |
| 125 | layers::kernels::common::Fill(tensor_data_ptr + line.size(), |
| 126 | static_cast<size_t>(m) - line.size(), |
| 127 | pad_val, DLDeviceType::kDLCPU); |
| 128 | } |
| 129 | } |
| 130 | if (device_type == DLDeviceType::kDLGPU) { |
| 131 | core::Copy<T>(cpu_tensor, *output_tensor); |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | // do inference |
| 136 | std::vector<float> operator()( |
| 137 | const std::vector<std::vector<int64_t>> &inputs, |
| 138 | const std::vector<std::vector<int64_t>> &poistion_ids, |
nothing calls this directly
no outgoing calls
no test coverage detected