{"record":{"id":"fca74daa70f10bae","repo":"dotnet/machinelearning","slug":"softmax-s-pfa-exporter-is-not-implemented-yet","errorCode":null,"errorMessage":"Softmax's PFA exporter is not implemented yet.","messagePattern":"Softmax's PFA exporter is not implemented yet\\.","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.ML.StandardTrainers/Standard/MulticlassClassification/OneVersusAllTrainer.cs","lineNumber":911,"sourceCode":"\n            private void NormalizeSoftmax(float[] scores, int count)\n            {\n                double sum = 0;\n                var score = new double[count];\n\n                for (int i = 0; i < count; i++)\n                {\n                    score[i] = Math.Exp(scores[i]);\n                    sum += score[i];\n                }\n\n                for (int i = 0; i < count; i++)\n                    scores[i] = (float)(score[i] / sum);\n            }\n\n            public override JToken SaveAsPfa(BoundPfaContext ctx, JToken input)\n            {\n                throw new NotImplementedException(\"Softmax's PFA exporter is not implemented yet.\");\n            }\n\n            public override bool SaveAsOnnx(OnnxContext ctx, string[] outputNames, string featureColumn)\n            {\n                Contracts.Assert(outputNames.Length >= 2);\n                const int minimumOpSetVersion = 9;\n                ctx.CheckOpSetVersion(minimumOpSetVersion, LoaderSignature);\n\n                var probabilityOutputs = base.SaveAsOnnxPreProcess(ctx, featureColumn, false);\n\n                string opType;\n                opType = \"Concat\";\n                var type = new VectorDataViewType(NumberDataViewType.Single, probabilityOutputs.Length);\n                var concatOutput = ctx.AddIntermediateVariable(type, \"ConcatOutputSoftMax\");\n                var concatNode = ctx.CreateNode(opType, probabilityOutputs, new[] { concatOutput }, ctx.GetNodeName(opType), \"\");\n                concatNode.AddAttribute(\"axis\", 1);\n\n                opType = \"Exp\";","sourceCodeStart":893,"sourceCodeEnd":929,"githubUrl":"https://github.com/dotnet/machinelearning/blob/7b76e69cf964daeca3f1377af6bc5543284d56c6/src/Microsoft.ML.StandardTrainers/Standard/MulticlassClassification/OneVersusAllTrainer.cs#L893-L929","documentation":"The OneVersusAll trainer wraps a binary trainer into a multiclass model. Its softmax model parameters implement SaveAsPfa (export to Portable Format for Analytics) by throwing NotImplementedException because PFA export for the softmax combiner was never written.","triggerScenarios":"Training a multiclass model with OneVersusAllTrainer (whose calibration is softmax) and then calling the PFA export path, e.g. via schema/export pipelines that convert the model to PFA (ml.NET PFA conversion APIs).","commonSituations":"Exporting a trained OneVsAll/softmax model for scoring in another runtime (e.g. a PFA-compatible serving system); CI jobs that auto-export all trained models to PFA; upgrading tooling that newly exercises the PFA exporter.","solutions":["Use ONNX export instead of PFA (SaveAsOnnx is implemented for softmax with opset >= 9).","Choose a different combiner/calibration that supports PFA export, or use a trainer whose multiclass output is directly PFA-exportable.","Implement SaveAsPfa for the softmax parameters in a fork/patch of Microsoft.ML.","Catch the NotImplementedException at export time and skip PFA export with a warning for softmax-based models."],"exampleFix":"// before\nvar pipeline = mlContext.MulticlassClassification.Trainers.OneVersusAll(binaryTrainer);\nvar pfa = converter.ConvertToPfa(model); // throws\n// after\nvar pipeline = mlContext.MulticlassClassification.Trainers.OneVersusAll(binaryTrainer);\nusing var onnxStream = mlContext.Model.ConvertToOnnx(model, data); // supported path","handlingStrategy":"fallback","validationCode":"bool supportsPfa = model is not OneVersusAllModelParameters { }; // detect softmax OvA before export","typeGuard":null,"tryCatchPattern":"try { ExportPfa(model); }\ncatch (NotImplementedException) { ExportOnnx(model); // softmax PFA unsupported\n}","preventionTips":["Check exporter support per model type before wiring PFA export into pipelines","Prefer ONNX export for OneVersusAll/softmax models","Pin to a fork/patch if PFA export is a hard requirement"],"tags":["pfa","export","not-implemented","softmax","one-versus-all"],"backgroundTag":"method-not-implemented","analyzedSha":"7b76e69cf964daeca3f1377af6bc5543284d56c6","analyzedAt":"2026-09-11T12:35:38.930Z","contentChangedAt":"2026-09-11T12:35:38.930Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}