| 259 | } |
| 260 | |
| 261 | bool ModelServer::BatchPredictUserEmbedding( |
| 262 | const std::vector<features_t>& batch_user_features, |
| 263 | std::vector<embedding_t>* embeddings) const { |
| 264 | if (!graph_ || !model_) { |
| 265 | return false; |
| 266 | } |
| 267 | |
| 268 | OpContext op_context; |
| 269 | op_context.Init(graph_.get(), model_->mutable_param()); |
| 270 | if (!op_context.InitOp({target_name_}, -1)) { |
| 271 | return false; |
| 272 | } |
| 273 | |
| 274 | Instance* inst = op_context.mutable_inst(); |
| 275 | auto& X = inst->insert<csr_t>(instance_name::X_USER_FEATURE_NAME); |
| 276 | for (const auto& features : batch_user_features) { |
| 277 | EmplaceRow(features, &X); |
| 278 | } |
| 279 | inst->set_batch(X.row()); |
| 280 | |
| 281 | op_context.InitPredict(); |
| 282 | op_context.Predict(); |
| 283 | const auto& hidden = op_context.hidden().get<tsr_t>(target_name_); |
| 284 | DXASSERT(hidden.is_rank(2)); |
| 285 | int col = hidden.dim(1); |
| 286 | DXASSERT(hidden.same_shape(X.row(), col)); |
| 287 | embeddings->resize(X.row()); |
| 288 | const float_t* _P = hidden.data(); |
| 289 | embeddings->resize(X.row()); |
| 290 | for (int i = 0; i < X.row(); ++i) { |
| 291 | auto& embedding = (*embeddings)[i]; |
| 292 | embedding.resize(col); |
| 293 | for (int j = 0; j < col; ++j) { |
| 294 | embedding[j] = (float)*_P; |
| 295 | ++_P; |
| 296 | } |
| 297 | } |
| 298 | return true; |
| 299 | } |
| 300 | |
| 301 | bool ModelServer::BatchGraphDeepFMPredict( |
| 302 | const std::vector<features_t>& batch_features, |
no test coverage detected