| 577 | |
| 578 | |
| 579 | static void SaveModel( |
| 580 | const TTrainingDataProviders& trainingDataForCpu, |
| 581 | const TLearnContext& ctx, |
| 582 | TMaybe<TFullModel*> initModel, |
| 583 | TMaybe<ui32> initLearnProgressLearnAndTestQuantizedFeaturesCheckSum, |
| 584 | TFullModel* dstModel |
| 585 | ) { |
| 586 | const auto& target = ctx.LearnProgress->AveragingFold.LearnTarget; |
| 587 | const TQuantizedFeaturesInfo& quantizedFeaturesInfo |
| 588 | = *(trainingDataForCpu.Learn->ObjectsData->GetQuantizedFeaturesInfo()); |
| 589 | |
| 590 | TPerfectHashedToHashedCatValuesMap perfectHashedToHashedCatValuesMap |
| 591 | = quantizedFeaturesInfo.CalcPerfectHashedToHashedCatValuesMap(ctx.LocalExecutor); |
| 592 | if (ctx.OutputOptions.AllowWriteFiles()) { |
| 593 | TString tmpDir; |
| 594 | NCB::NPrivate::CreateTrainDirWithTmpDirIfNotExist(ctx.OutputOptions.GetTrainDir(), &tmpDir); |
| 595 | quantizedFeaturesInfo.UnloadCatFeaturePerfectHashFromRam(tmpDir); |
| 596 | } |
| 597 | |
| 598 | const TQuantizedEstimatedFeaturesInfo onlineQuantizedEstimatedFeaturesInfo |
| 599 | = ctx.LearnProgress->GetOnlineEstimatedFeaturesInfo(); |
| 600 | |
| 601 | TModelTrees modelTrees; |
| 602 | THashMap<TFeatureCombination, TProjection> featureCombinationToProjectionMap; |
| 603 | const std::function<TModelSplit(TSplit)> getModelSplit = [&] (const TSplit& split) { |
| 604 | auto modelSplit = split.GetModelSplit( |
| 605 | ctx, |
| 606 | perfectHashedToHashedCatValuesMap, |
| 607 | *trainingDataForCpu.FeatureEstimators, |
| 608 | trainingDataForCpu.EstimatedObjectsData.QuantizedEstimatedFeaturesInfo, |
| 609 | onlineQuantizedEstimatedFeaturesInfo |
| 610 | ); |
| 611 | if (modelSplit.Type == ESplitType::OnlineCtr) { |
| 612 | featureCombinationToProjectionMap[modelSplit.OnlineCtr.Ctr.Base.Projection] = split.Ctr.Projection; |
| 613 | } |
| 614 | return modelSplit; |
| 615 | }; |
| 616 | if (ctx.Params.ObliviousTreeOptions->GrowPolicy == EGrowPolicy::SymmetricTree) { |
| 617 | TObliviousTreeBuilder builder( |
| 618 | ctx.LearnProgress->FloatFeatures, |
| 619 | ctx.LearnProgress->CatFeatures, |
| 620 | ctx.LearnProgress->TextFeatures, |
| 621 | ctx.LearnProgress->EmbeddingFeatures, |
| 622 | ctx.LearnProgress->ApproxDimension); |
| 623 | for (size_t treeId = 0; treeId < ctx.LearnProgress->TreeStruct.size(); ++treeId) { |
| 624 | TVector<TModelSplit> modelSplits; |
| 625 | Y_ASSERT(std::holds_alternative<TSplitTree>(ctx.LearnProgress->TreeStruct[treeId])); |
| 626 | TVector<TSplit> splits = std::get<TSplitTree>(ctx.LearnProgress->TreeStruct[treeId]).Splits; |
| 627 | for (const auto& split : splits) { |
| 628 | modelSplits.push_back(getModelSplit(split)); |
| 629 | } |
| 630 | builder.AddTree(modelSplits, ctx.LearnProgress->LeafValues[treeId], ctx.LearnProgress->TreeStats[treeId].LeafWeightsSum); |
| 631 | } |
| 632 | builder.Build(&modelTrees); |
| 633 | } else { |
| 634 | TNonSymmetricTreeModelBuilder builder( |
| 635 | ctx.LearnProgress->FloatFeatures, |
| 636 | ctx.LearnProgress->CatFeatures, |
no test coverage detected