{"id":49296,"date":"2023-11-27T16:00:00","date_gmt":"2023-11-28T00:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=49296"},"modified":"2024-01-12T11:30:28","modified_gmt":"2024-01-12T19:30:28","slug":"announcing-ml-net-3-0","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-ml-net-3-0\/","title":{"rendered":"Announcing ML.NET 3.0"},"content":{"rendered":"<p><a href=\"https:\/\/dot.net\/ml\">ML.NET<\/a> is an open-source, cross-platform machine learning framework for .NET developers that enables integration of custom machine learning models into .NET applications. <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.ML\/3.0.0\">ML.NET version 3.0<\/a> is now released, with lots of new features and enhancements!<\/p>\n<p>Deep Learning scenarios were substantially expanded in this release with new capabilities in Object Detection, Named Entity Recognition, and Question Answering. That&#8217;s all possible because of integrations and interoperability with TorchSharp and ONNX models. We&#8217;ve also updated our integration with LightGBM to the latest version.<\/p>\n<p>Data processing scenarios are greatly improved with a long list of enhancements and bug fixes to <code>DataFrame<\/code>, as well as new <code>IDataView<\/code> interoperability features. The important steps of loading, inspecting, transforming, and visualizing your data are much more powerful.<\/p>\n<p>While this post highlights several aspects of the ML.NET 3.0 release, the full list of updates is available in the <a href=\"https:\/\/github.com\/dotnet\/machinelearning\/blob\/main\/docs\/release-notes\/3.0\/release-3.0.0.md\">release notes<\/a>.<\/p>\n<h2>Deep Learning<\/h2>\n<p>Over the past year, we&#8217;ve all witnessed an acceleration of growth in deep learning scenarios and capabilities. With ML.NET 3.0, you can leverage many of these advancements within your .NET applications.<\/p>\n<h3>Object Detection<\/h3>\n<p>Object detection is a computer vision problem. While closely related to image classification, object detection performs image classification at a more granular scale. Object detection both locates and categorizes entities within images. It&#8217;s best to use object detection when images contain multiple objects of different types.<\/p>\n<p>We announced <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/object-detection-ml-dotnet-model-builder\/\">Object Detection in ML.NET Model Builder<\/a> earlier this year. Those capabilities are built on top of the TorchSharp-powered Object Detection APIs introduced in ML.NET 3.0 (<a href=\"https:\/\/github.com\/dotnet\/machinelearning\/pull\/6605\">PR #6605<\/a>).<\/p>\n<p>Under the covers, the Object Detection API leverages some of the latest techniques from Microsoft Research and is backed by a Transformer-based neural network architecture built with TorchSharp. For more details on the underlying model, see the <a href=\"https:\/\/arxiv.org\/pdf\/2111.14725.pdf\">Searching the Space of Vision Transformer<\/a> paper.<\/p>\n<p>Object Detection is included in the <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.ML.TorchSharp\/3.0.0\">Microsoft.ML.TorchSharp 3.0.0 package<\/a> within the <code>Microsoft.ML.TorchSharp<\/code> and <code>Microsoft.ML.TorchSharp.AutoFormerV2<\/code> namespaces. Read the <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/object-detection-ml-dotnet-model-builder\/\">Object Detection in ML.NET Model Builder<\/a> blog post for an in-depth look.<\/p>\n<pre><code class=\"language-c#\">var chain = new EstimatorChain&lt;ITransformer&gt;();\r\n\r\nvar filteredPipeline = chain. Append(\r\n        mlContext.Transforms.Text.TokenizeIntoWords(labelColumnName, separators: [',']),\r\n        TransformerScope.Training\r\n    )\r\n    .Append(\r\n        mlContext.Transforms.Conversion.MapValueToKey(labelColumnName),\r\n        TransformerScope.Training\r\n    )\r\n    .Append(\r\n        mlContext.Transforms.Text.TokenizeIntoWords(boundingBoxColumnName, separators: [',']),\r\n        TransformerScope.Training\r\n    )\r\n    .Append(\r\n        mlContext.Transforms.Conversion.ConvertType(boundingBoxColumnName),\r\n        TransformerScope.Training\r\n    )\r\n    .Append(mlContext.Transforms.LoadImages(\"Image\", imageFolder, \"ImagePath\"))\r\n    .Append(\r\n        mlContext.MulticlassClassification.Trainers.ObjectDetection(\r\n            labelColumnName, predictedLabelColumnName, scoreColumnName,\r\n            boundingBoxColumnName, predictedBoundingBoxColumnName,\r\n            imageColumnName, maxEpoch\r\n        )\r\n    )\r\n    .Append(mlContext.Transforms.Conversion.MapKeyToValue(predictedLabelColumnName));\r\n\r\nvar options = new ObjectDetectionTrainer.Options()\r\n{\r\n    LabelColumnName = labelColumnName,\r\n    BoundingBoxColumnName = boundingBoxColumnName,\r\n    ScoreThreshold = .5,\r\n    MaxEpoch = maxEpoch,\r\n    LogEveryNStep = 1,\r\n};\r\n\r\nvar pipeline = mlContext.Transforms.Text.TokenizeIntoWords(labelColumnName, separators: [','])\r\n    .Append(mlContext.Transforms.Conversion.MapValueToKey(labelColumnName))\r\n    .Append(mlContext.Transforms.Text.TokenizeIntoWords(boundingBoxColumnName, separators: [',']))\r\n    .Append(mlContext.Transforms.Conversion.ConvertType(boundingBoxColumnName))\r\n    .Append(mlContext.Transforms.LoadImages(\"Image\", imageFolder, \"ImagePath\"))\r\n    .Append(mlContext.MulticlassClassification.Trainers.ObjectDetection(options))\r\n    .Append(mlContext.Transforms.Conversion.MapKeyToValue(predictedLabelColumnName));\r\n\r\nvar model = pipeline.Fit(data);\r\nvar idv = model.Transform(data);\r\n\r\nvar metrics = ML.MulticlassClassification.EvaluateObjectDetection(\r\n    idv, idv.Schema[2], idv.Schema[boundingBoxColumnName], idv.Schema[predictedLabelColumnName],\r\n    idv.Schema[predictedBoundingBoxColumnName], idv.Schema[scoreColumnName]\r\n);<\/code><\/pre>\n<h3>Named Entity Recognition and Question Answering<\/h3>\n<p>Natural Language Processing is one of the most common ML needs in software. Two of the most substantial areas of advancement in NLP have been Question Answering (QA) and Named Entity Recognition (NER). Both of these scenarios are unlocked in ML.NET 3.0 by building on top of the existing TorchSharp RoBERTa text classification features introduced in ML.NET 2.0.<\/p>\n<p>Both the NER and QA trainers are included in the <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.ML.TorchSharp\/3.0.0\">Microsoft.ML.TorchSharp 3.0.0 package<\/a> and the <code>Microsoft.ML.TorchSharp<\/code> namespace.<\/p>\n<pre><code class=\"language-c#\">\/\/ QA trainer\r\nvar chain = new EstimatorChain&lt;ITransformer&gt;();\r\nvar estimatorQA = chain.Append(mlContext.MulticlassClassification.Trainers.QuestionAnswer(\r\n    contextColumnName, questionColumnName, trainingAnswerColumnName,\r\n    answerIndexColumnName, predictedAnswerColumnName, scoreColumnName,\r\n    topK, batchSize, maxEpochs, architecture, validationSet\r\n));\r\n\r\n\/\/ NER trainer\r\nvar estimatorNER = chain.Append(mlContext.Transforms.Conversion.MapValueToKey(\"Label\", keyData))\r\n    .Append(mlContext.MulticlassClassification.Trainers.NameEntityRecognition(\r\n        labelColumnName, outputColumnName, sentence1ColumnName,\r\n        batchSize, maxEpochs, architecture, validationSet\r\n    ))\r\n    .Append(mlContext.Transforms.Conversion.MapKeyToValue(outputColumn));<\/code><\/pre>\n<h2>Intel oneDAL Training Acceleration<\/h2>\n<p>Shortly after we released ML.NET 2.0, we announced training hardware acceleration powered by Intel oneDAL as part of the first preview of ML.NET 3.0. Intel oneDAL (<a href=\"https:\/\/www.intel.com\/content\/www\/us\/en\/developer\/tools\/oneapi\/onedal.html\">Intel oneAPI Data Analytics Library<\/a>) is a library that helps speed up data analysis by providing highly optimized algorithmic building blocks for all stages of the data analytics and machine learning process. Intel oneDAL makes use of the SIMD extensions in 64-bit architectures, which are featured in Intel and AMD CPUs.<\/p>\n<p>Refer back to the <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/accelerate-ml-net-training-with-intel-onedal\/\">Accelerate ML.NET training with Intel oneDAL<\/a> blog post for more on this feature set.<\/p>\n<h2>Automated Machine Learning (AutoML)<\/h2>\n<p>Automated Machine Learning (AutoML) automates the process of applying machine learning to data. AutoML powers experiences like those found in Model Builder and the ML.NET CLI.<\/p>\n<p>With ML.NET 3.0, the AutoML experience gained several new capabilities. The AutoML Sweeper now supports Sentence Similarity, Question Answering, and Object Detection. Community member <a href=\"https:\/\/github.com\/torronen\">Antti &#8220;Andy&#8221; T\u00f6rr\u00f6nen (@torronen)<\/a> implemented a sampling key column name (<code>SamplingKeyColumnName<\/code>) that can be used with <code>SetDataset<\/code> to more easily set the sampling key name. The <code>AutoZero<\/code> tuner can now be used in <code>BinaryClassification<\/code> experiments. The maximum number of models used for an experiment can be specified through <code>ExperimentSettings.MaxModel<\/code>.<\/p>\n<p>Thanks to community member <a href=\"https:\/\/github.com\/andrasfuchs\">Andras Fuchs (@andrasfuchs)<\/a>, continuous resource monitoring is available through <code>AutoML.IMonitor<\/code>. This allows monitoring of memory demand, virtual memory usage, and remaining disk space. With that monitoring, long-running experiments can be controlled through a custom <code>IMonitor<\/code> implementation to avoid crashes and failed trials.<\/p>\n<h2>DataFrame<\/h2>\n<p>This release includes a long list of notable updates to <code>DataFrame<\/code>, many of which were completed by a community member, <a href=\"https:\/\/github.com\/asmirnov82\">Aleksei Smirnov (@asmirnov82)<\/a>. We appreciate Aleksei&#8217;s contributions and we&#8217;re sure you will too!<\/p>\n<p>To enable more <code>IDataView<\/code> &lt;-&gt; <code>DataFrame<\/code> conversions, support for both <code>String<\/code> and <code>VBuffer<\/code> column types have been added. <code>String<\/code> values are handled as <code>ReadOnlyMemory&lt;char&gt;<\/code> , and the <code>VBufferDataFrameColumn&lt;T&gt;<\/code> column type supports all backing primitives. Columns can now store more than 2 Gb of data as well, with the previous limitation being removed. Apache Arrow <code>Date64<\/code> column data is recognized now too.<\/p>\n<p>Data loading scenarios for <code>DataFrame<\/code> are expanded in ML.NET 3.0. Data can now be imported from and exported to SQL databases thanks to community member, <a href=\"https:\/\/github.com\/andrei-faber\">Andrei Faber (@andrei-faber)<\/a>. This is accomplished using ADO.NET, which supports a large number of SQL-compatible databases. As part of this implementation, it also became possible to load data from any <code>IEnumerable<\/code> collection and export data to <code>System.Data.DataTable<\/code>. Data from one <code>DataFrame<\/code> can now be appended into another <code>DataFrame<\/code> when their column names match, relaxing a previous constraint on column ordering. Comma-separated data loaded through <code>DataFrame.LoadCsv<\/code> can now handle duplicate column names too, with the option to rename duplicate columns.<\/p>\n<p>There were many other enhancements and fixes to <code>DataFrame<\/code> too. Arithmetic performance was improved in column cloning and binary comparison scenarios. Null value handling was improved while performing arithmetic operations, requiring fewer steps of transforming and cleaning data. There were even debugger improvements that produce more readable output for columns with long names.<\/p>\n<h2>Tensor Primitives Integration<\/h2>\n<p>Tensor Primitives is short for <code>System.Numerics.Tensors.TensorPrimitives<\/code>, a new set of APIs that introduce support for tensor operations. As part of .NET 8, our team released a new <a href=\"https:\/\/www.nuget.org\/packages\/System.Numerics.Tensors\/8.0.0\">System.Numerics.Tensors<\/a> package that introduced Tensor Primitives. The Tensor Primitives APIs are the next step in the evolution of Numerics for AI in .NET, building on the momentum of hardware intrinsics and Generic Math.<\/p>\n<p>While the integration with Tensor Primitives is purely an implementation detail that doesn&#8217;t affect the public surface area of ML.NET, it brings some notable performance improvements. The following benchmark results illustrate the gains while targeting .NET 8.<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: right\">Method<\/th>\n<th style=\"text-align: right\">arrayLength<\/th>\n<th style=\"text-align: right\">Mean &#8211; Original<\/th>\n<th style=\"text-align: right\">Mean &#8211; New<\/th>\n<th style=\"text-align: right\">% Faster<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: right\">AddScalarU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">25.30 ns<\/td>\n<td style=\"text-align: right\">20.32 ns<\/td>\n<td style=\"text-align: right\">25%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">Scale<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">19.91 ns<\/td>\n<td style=\"text-align: right\">19.29 ns<\/td>\n<td style=\"text-align: right\">3%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">ScaleSrcU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">27.58 ns<\/td>\n<td style=\"text-align: right\">20.74 ns<\/td>\n<td style=\"text-align: right\">33%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">ScaleAddU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">28.46 ns<\/td>\n<td style=\"text-align: right\">29.05 ns<\/td>\n<td style=\"text-align: right\">&#8212;<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">AddScaleU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">29.74 ns<\/td>\n<td style=\"text-align: right\">28.59 ns<\/td>\n<td style=\"text-align: right\">4%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">AddScaleSU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">345.92 ns<\/td>\n<td style=\"text-align: right\">327.68 ns<\/td>\n<td style=\"text-align: right\">6%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">AddScaleCopyU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">34.01 ns<\/td>\n<td style=\"text-align: right\">27.03 ns<\/td>\n<td style=\"text-align: right\">26%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">AddU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">29.80 ns<\/td>\n<td style=\"text-align: right\">26.71 ns<\/td>\n<td style=\"text-align: right\">12%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">AddSU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">325.32 ns<\/td>\n<td style=\"text-align: right\">349.46 ns<\/td>\n<td style=\"text-align: right\">&#8212;<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">MulElementWiseU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">33.92 ns<\/td>\n<td style=\"text-align: right\">27.29 ns<\/td>\n<td style=\"text-align: right\">24%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">Sum<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">36.57 ns<\/td>\n<td style=\"text-align: right\">34.34 ns<\/td>\n<td style=\"text-align: right\">6%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">SumSqU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">37.50 ns<\/td>\n<td style=\"text-align: right\">39.34 ns<\/td>\n<td style=\"text-align: right\">-5%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">SumSqDiffU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">41.23 ns<\/td>\n<td style=\"text-align: right\">43.38 ns<\/td>\n<td style=\"text-align: right\">&#8212;<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">SumAbsU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">43.74 ns<\/td>\n<td style=\"text-align: right\">39.27 ns<\/td>\n<td style=\"text-align: right\">11%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">SumAbsDiffU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">47.23 ns<\/td>\n<td style=\"text-align: right\">37.48 ns<\/td>\n<td style=\"text-align: right\">26%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">MaxAbsU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">42.30 ns<\/td>\n<td style=\"text-align: right\">43.26 ns<\/td>\n<td style=\"text-align: right\">&#8212;<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">MaxAbsDiffU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">46.94 ns<\/td>\n<td style=\"text-align: right\">47.73 ns<\/td>\n<td style=\"text-align: right\">&#8212;<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">DotU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">50.34 ns<\/td>\n<td style=\"text-align: right\">43.20 ns<\/td>\n<td style=\"text-align: right\">17%<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">DotSU<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">212.19 ns<\/td>\n<td style=\"text-align: right\">213.18 ns<\/td>\n<td style=\"text-align: right\">&#8212;<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\">Dist2<\/td>\n<td style=\"text-align: right\">512<\/td>\n<td style=\"text-align: right\">55.48 ns<\/td>\n<td style=\"text-align: right\">47.43 ns<\/td>\n<td style=\"text-align: right\">17%<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>More details and the .NET Framework benchmark results are included in the <a href=\"https:\/\/github.com\/dotnet\/machinelearning\/pull\/6875\">dotnet\/machinelearning#6875<\/a> pull request that introduced this integration.<\/p>\n<p>Beyond these performance gains, we also used this integration opportunity as a means for testing the API shape, usability, functionality, and correctness of the <code>TensorPrimitives<\/code> APIs. Proving that the APIs could satisfy the ML.NET scenarios was a valuable step toward bringing the System.Numerics.Tensors package out of preview with a stable 8.0.0 version.<\/p>\n<h2>What&#8217;s Next<\/h2>\n<p>With the .NET 8 and ML.NET 3.0 releases completed, we are working on our plans for .NET 9 and ML.NET 4.0. Much sooner than that though, you can expect Model Builder and the ML.NET CLI to be updated to consume the ML.NET 3.0 release.<\/p>\n<p>We know we will continue expanding deep learning scenarios and integrations, and we know we will keep making enhancements to DataFrame. We will keep expanding the APIs available in System.Numerics.Tensors and integrating them into ML.NET. Stay tuned for more detailed ML.NET 4.0 plans.<\/p>\n<h2>Get started and resources<\/h2>\n<p>Learn more about ML.NET, Model Builder, and the ML.NET CLI at <a href=\"https:\/\/learn.microsoft.com\/dotnet\/machine-learning\/\">Microsoft Learn<\/a>.<\/p>\n<p>If you run into any issues, feature requests, or feedback, please file an issue in the <a href=\"https:\/\/github.com\/dotnet\/machinelearning\">ML.NET repo<\/a>.<\/p>\n<p>Join the <a href=\"https:\/\/aka.ms\/virtual-mlnet-community-discord\">ML.NET Community Discord<\/a> or #machine-learning channel on the <a href=\"https:\/\/aka.ms\/dotnet-discord\">.NET Development Discord<\/a>.<\/p>\n<p>Tune in to the <a href=\"https:\/\/dotnet.microsoft.com\/live\/community-standup\">Machine Learning .NET Community Standup<\/a> every other Wednesday at 10am Pacific Time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Announcing ML.NET 3.0, with improvements for deep learning, DataFrame, performance, and more!<\/p>\n","protected":false},"author":4267,"featured_media":49297,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,328,688,691],"tags":[],"class_list":["post-49296","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-aiml","category-machine-learning","category-ml-dotnet"],"acf":[],"blog_post_summary":"<p>Announcing ML.NET 3.0, with improvements for deep learning, DataFrame, performance, and more!<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/49296","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/4267"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=49296"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/49296\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/49297"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=49296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=49296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=49296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}