From e41eaa67563ba619fabb073af1a98d19a805548d Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 9 Jan 2026 12:52:30 -0600 Subject: [PATCH 001/111] Create a guide for ML-BOM relative to CycloneDX v1.7 schema Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x10-Introduction.md | 27 +++++++++++++++---- ML-BOM/en/0x15-Core-Concepts.md | 25 +++++++++++++++++ ML-BOM/en/0x20-Object-Model.md | 16 +++++++++++ ML-BOM/en/0x30-Use_Case_Software_Simple.md | 3 +++ ML-BOM/en/0x90-Appendix-A_Glossary.md | 7 +++++ ML-BOM/en/0x91-Appendix-B_References.md | 31 ++++++++++++++++++++++ 6 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 ML-BOM/en/0x15-Core-Concepts.md create mode 100644 ML-BOM/en/0x20-Object-Model.md create mode 100644 ML-BOM/en/0x30-Use_Case_Software_Simple.md create mode 100644 ML-BOM/en/0x90-Appendix-A_Glossary.md create mode 100644 ML-BOM/en/0x91-Appendix-B_References.md diff --git a/ML-BOM/en/0x10-Introduction.md b/ML-BOM/en/0x10-Introduction.md index fbcfe0d..affa955 100644 --- a/ML-BOM/en/0x10-Introduction.md +++ b/ML-BOM/en/0x10-Introduction.md @@ -1,10 +1,27 @@ # Introduction -CycloneDX is a modern standard for the software supply chain. At its core, CycloneDX is a general-purpose Bill of -Materials (BOM) standard capable of representing software, hardware, services, and other types of inventory. CycloneDX -is an OWASP flagship project, has a formal standardization process and governance model through -[Ecma Technical Committee 54](https://tc54.org), and is supported by the global information security community. -TODO +CycloneDX is a modern standard for the software supply chain. At its core, CycloneDX is a general-purpose Bill-of-Materials (BOM) standard capable of representing software, hardware, services, and other types of inventory. + +CycloneDX is notably an OWASP flagship project, has a formal standardization process and governance model through [Ecma Technical Committee 54](https://tc54.org), and is supported by the global information security community. + +## What is an ML-BOM? + +An ML-BOM (Machine Learning Bill-of-Materials) is a CycloneDX BOM document specialized to address the unique complexities and risks of AI/ML systems. It provides a detailed inventory of all components, configurations, and processes involved in the development, training, deployment and hosting (i.e., via hardware/software stacks and frameworks) of a machine learning model. + +The primary purpose of an ML-BOM is to ensure transparency, traceability, security, and compliance throughout an ML model's lifecycle. + + +### Why ML-BOMs are Important + +ML-BOMs address critical challenges in the machine learning supply chain: + +- **Security & Vulnerability Management**: Help identify security risks, such as malicious (open-source) models or vulnerable dependencies, before they are integrated into production applications. + +- **Governance & Compliance**: Support alignment with emerging global AI regulations and standards, such as the [European Union's Cyber Resilience Act (EU CRA)](https://www.european-cyber-resilience-act.com/) and the [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework), by providing necessary documentation for audits. + +- **Risk Mitigation**: Enable teams to track data lineage, helping to identify potential data quality issues, privacy risks, or biases that could affect the model's performance and fairness. + +- **Reproducibility & Explainability**: Provide a detailed record of components and training processes such that developers are able to reproduce models (via training from data sets) and their benchmarks and further validate claims on their accuracy and adherence to ethical considerations.
\newpage diff --git a/ML-BOM/en/0x15-Core-Concepts.md b/ML-BOM/en/0x15-Core-Concepts.md new file mode 100644 index 0000000..f4cf3e8 --- /dev/null +++ b/ML-BOM/en/0x15-Core-Concepts.md @@ -0,0 +1,25 @@ +# Core Concepts and Architecture + +### Key Components of an ML-BOM + +An ML-BOM typically documents the identifying elements, architecture, components and its supply chain along with any configurations and developmental or executional considerations including: + +- **Model metadata**: Descriptive details such as the model's name, version, developer, purpose, use cases, architecture, (hyper)parameters and any additional identifying elements. + +- **Model Architecture**: Description of the composition of the model's neural network including configurations, layers, input/output parameters, attention mechanisms, etc. used at network processing stages. + +- **Datasets**: Description of datasets, as CycloneDX data components, used for training and testing of the associated model. This includes data sources, selection criteria, acquisition methods, preprocessing steps and more. + +- **Tokenizers and prompt templates**: Descriptive details of specific tokenizers (e.g., libraries, files, configurations) and prompt templates used to train and/or for execution of the model. + +- **Software & Frameworks**: A list of all hardware and software components including libraries, packages, frameworks (e.g., TensorFlow, PyTorch, Huggingface), along with specific versions and associated licenses used in aspects of the model's lifecycle. + +- **Training & Environment Details**: Information about the computational environment (software, hardware, operating system, and GPUs) used for training, hyperparameters, and evaluation metrics. + +- **Usage & Ethics**: Documentation of the model's intended use, known limitations, safety guardrails, and ethical considerations. + +- **Environmental Impacts**: Documentation of the resource needed to train or execute the model which have an environmental impact or cost (e.g., data center energy and water cooling cost details). + +
+\newpage +
diff --git a/ML-BOM/en/0x20-Object-Model.md b/ML-BOM/en/0x20-Object-Model.md new file mode 100644 index 0000000..84fc4a4 --- /dev/null +++ b/ML-BOM/en/0x20-Object-Model.md @@ -0,0 +1,16 @@ +# CycloneDX Object Model + +## Overview +TBD + +## Object schema + +#### Common CycloneDX schema used for ML-BOM + +#### ML-BOM-specific schema + +TBD + +
+\newpage +
diff --git a/ML-BOM/en/0x30-Use_Case_Software_Simple.md b/ML-BOM/en/0x30-Use_Case_Software_Simple.md new file mode 100644 index 0000000..6a61dab --- /dev/null +++ b/ML-BOM/en/0x30-Use_Case_Software_Simple.md @@ -0,0 +1,3 @@ +## Use Cases: TBD + + diff --git a/ML-BOM/en/0x90-Appendix-A_Glossary.md b/ML-BOM/en/0x90-Appendix-A_Glossary.md new file mode 100644 index 0000000..c469e50 --- /dev/null +++ b/ML-BOM/en/0x90-Appendix-A_Glossary.md @@ -0,0 +1,7 @@ +# Appendix A: Glossary + +- TBD + +
+\newpage +
diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md new file mode 100644 index 0000000..5221152 --- /dev/null +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -0,0 +1,31 @@ +# Appendix B: References + +The following resources may be useful to users and adopters of the CycloneDX standard and its ML-BOM profile: + +#### Standards and regulatory references + +* [Ecma Technical Committee 54](https://tc54.org) +* [European Union's Cyber Resilience Act (EU CRA)](https://www.european-cyber-resilience-act.com/) +* [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework) + +#### CycloneDX resources + +* [OWASP CycloneDX](https://cyclonedx.org/) +* OWASP CycloneDX [Tool Center](https://cyclonedx.org/tool-center/) +* OWASP CycloneDX [BOM Repository Server](https://github.com/CycloneDX/cyclonedx-bom-repo-server) +* [OWASP Dependency-Track](https://dependencytrack.org/) +* [OWASP Software Component Verification Standard (SCVS)](https://scvs.owasp.org/) + * [SCVS BOM Maturity Model](https://scvs.owasp.org/bom-maturity-model/) +* Package-URL specification: [https://github.com/package-url/purl-spec/](https://github.com/package-url/purl-spec/) + +#### Referenced standards + +* [OpenChain](https://www.openchainproject.org/) +* [SPDX License IDs](https://spdx.dev/ids/) +* [SPDX License List](https://spdx.org/licenses/) + +#### Technology references + +* [Huggingface](https://huggingface.co/) - an open-source platform and community for Artificial Intelligence (AI) and Machine Learning (ML). +* [PyTorch](https://pytorch.org/) - an optimized tensor library and framework used for deep learning on GPUs and CPUs. +* [TensorFlow](https://www.tensorflow.org/) - An end-to-end open source machine learning platform. From ddc2f3b641544646e7a52eb3ca25d6dc43ce8286 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 9 Jan 2026 14:12:49 -0600 Subject: [PATCH 002/111] Create a guide for ML-BOM relative to CycloneDX v1.7 schema Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x15-Core-Concepts.md | 6 +++--- ML-BOM/en/0x20-Object-Model.md | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ML-BOM/en/0x15-Core-Concepts.md b/ML-BOM/en/0x15-Core-Concepts.md index f4cf3e8..ce269ed 100644 --- a/ML-BOM/en/0x15-Core-Concepts.md +++ b/ML-BOM/en/0x15-Core-Concepts.md @@ -1,8 +1,8 @@ -# Core Concepts and Architecture +# Core Concepts and Considerations ### Key Components of an ML-BOM -An ML-BOM typically documents the identifying elements, architecture, components and its supply chain along with any configurations and developmental or executional considerations including: +An ML-BOM typically documents the identifying elements, architecture, components and its supply chain along with any configurations and developmental or executional considerations inclusive of the following areas: - **Model metadata**: Descriptive details such as the model's name, version, developer, purpose, use cases, architecture, (hyper)parameters and any additional identifying elements. @@ -10,7 +10,7 @@ An ML-BOM typically documents the identifying elements, architecture, components - **Datasets**: Description of datasets, as CycloneDX data components, used for training and testing of the associated model. This includes data sources, selection criteria, acquisition methods, preprocessing steps and more. -- **Tokenizers and prompt templates**: Descriptive details of specific tokenizers (e.g., libraries, files, configurations) and prompt templates used to train and/or for execution of the model. +- **Tokenizers and prompt templates**: Descriptive details of specific tokenizers (e.g., libraries, files, configurations) and prompt templates used to train and/or interact with the model during runtime. - **Software & Frameworks**: A list of all hardware and software components including libraries, packages, frameworks (e.g., TensorFlow, PyTorch, Huggingface), along with specific versions and associated licenses used in aspects of the model's lifecycle. diff --git a/ML-BOM/en/0x20-Object-Model.md b/ML-BOM/en/0x20-Object-Model.md index 84fc4a4..ce0ac4b 100644 --- a/ML-BOM/en/0x20-Object-Model.md +++ b/ML-BOM/en/0x20-Object-Model.md @@ -1,7 +1,10 @@ -# CycloneDX Object Model +# CycloneDX ML-BOM Object Model ## Overview -TBD + +An ML-BOM makes use of many of the common, core elements of the CycloneDX schema as well as unique aspects specific to ML components, their architectures, metadata, training and other information used to gauge adherence to regulatory compliance. + +This section will include specifics of how ML-related information should be conveyed using both using the CycloneDX schema. ## Object schema From 48816b3c02a153953ca25cac9c2bce22baaddd2e Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 12 Jan 2026 15:41:00 -0600 Subject: [PATCH 003/111] Create a guide for ML-BOM relative to CycloneDX v1.7 schema Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x15-Core-Concepts.md | 13 ++++-- ML-BOM/en/0x20-Design-Best-Practices.md | 62 +++++++++++++++++++++++++ ML-BOM/en/0x20-Object-Model.md | 19 -------- ML-BOM/en/0x91-Appendix-B_References.md | 14 ++++-- ML-BOM/en/images/anatomy.svg | 1 + 5 files changed, 82 insertions(+), 27 deletions(-) create mode 100644 ML-BOM/en/0x20-Design-Best-Practices.md delete mode 100644 ML-BOM/en/0x20-Object-Model.md create mode 100644 ML-BOM/en/images/anatomy.svg diff --git a/ML-BOM/en/0x15-Core-Concepts.md b/ML-BOM/en/0x15-Core-Concepts.md index ce269ed..7a8b104 100644 --- a/ML-BOM/en/0x15-Core-Concepts.md +++ b/ML-BOM/en/0x15-Core-Concepts.md @@ -4,21 +4,24 @@ An ML-BOM typically documents the identifying elements, architecture, components and its supply chain along with any configurations and developmental or executional considerations inclusive of the following areas: +- **Model identifiers**: Identifying information such as the model's [Package URL (PURL)](https://tc54.org/purl/) (e.g., from Huggingface `pkg:huggingface/distilbert-base-uncased@043235d6088ecd3dd5fb5ca3592b6913fd51602`) or other domain-specific identifiers within other registries. + - **Model metadata**: Descriptive details such as the model's name, version, developer, purpose, use cases, architecture, (hyper)parameters and any additional identifying elements. -- **Model Architecture**: Description of the composition of the model's neural network including configurations, layers, input/output parameters, attention mechanisms, etc. used at network processing stages. +- **Model architecture**: Description of the composition of the model's neural network including configurations, layers, input/output parameters, attention mechanisms, etc. used at network processing stages. - **Datasets**: Description of datasets, as CycloneDX data components, used for training and testing of the associated model. This includes data sources, selection criteria, acquisition methods, preprocessing steps and more. - **Tokenizers and prompt templates**: Descriptive details of specific tokenizers (e.g., libraries, files, configurations) and prompt templates used to train and/or interact with the model during runtime. -- **Software & Frameworks**: A list of all hardware and software components including libraries, packages, frameworks (e.g., TensorFlow, PyTorch, Huggingface), along with specific versions and associated licenses used in aspects of the model's lifecycle. +- **Hardware, software & frameworks**: A list of all hardware and software components including libraries, packages, frameworks (e.g., TensorFlow, PyTorch, Huggingface), along with specific versions and associated licenses used in aspects of the model's lifecycle. +This informational category may also include operational and application aspects of models (perhaps as agents) used within compositional frameworks and workflows along with the protocols used for communication. -- **Training & Environment Details**: Information about the computational environment (software, hardware, operating system, and GPUs) used for training, hyperparameters, and evaluation metrics. +- **Training & testing details**: Information about the computational environment and systems (software, hardware, operating system, and GPUs) used for training or evaluation along with necessary configurations, hyperparameters, and evaluation metrics. -- **Usage & Ethics**: Documentation of the model's intended use, known limitations, safety guardrails, and ethical considerations. +- **Intended use & ethics**: Documentation of the model's intended use, known limitations, safety guardrails, and ethical considerations. -- **Environmental Impacts**: Documentation of the resource needed to train or execute the model which have an environmental impact or cost (e.g., data center energy and water cooling cost details). +- **Environmental impacts**: Documentation of the resource needed to train or execute the model which have an environmental impact or cost (e.g., data center energy and water cooling cost details).
\newpage diff --git a/ML-BOM/en/0x20-Design-Best-Practices.md b/ML-BOM/en/0x20-Design-Best-Practices.md new file mode 100644 index 0000000..c03088f --- /dev/null +++ b/ML-BOM/en/0x20-Design-Best-Practices.md @@ -0,0 +1,62 @@ +# ML-BOM Design and Best Practices + +## Overview + +A Machine Learning Bill-of-Materials (MLBOM or ML-BOM) is an object model to describe a machine learning model, its compositional assets and other descriptive information often used to assess risk and compliance. Support for MLBOM is included in CycloneDX v1.5 and higher. + +An MLBOM makes use of many of the common, core elements of the CycloneDX schema as well as unique aspects specific to ML components, their architectures, metadata, training and other information used to gauge adherence to regulatory compliance. + +This section will include specifics and best practices of how ML-related information should be conveyed using both using the CycloneDX schema. + +The [Core Concepts](0x15-Core-Concepts.md#key-components-of-an-ml-bom) listed in the previous section will be used to provide details, best practices and examples of how to provide the corresponding information using CycloneDX schema objects. + +For convenience, here are links to the specific sections for each of those informational areas: + +- [Model representation](#model-representation) +- [Model identifiers](#model-identifiers) +- [Model metadata](#model-metadata) +- [Model architecture]() +- [Datasets]() +- [Tokenizers and prompt templates]() +- [Hardware, software & frameworks]() +- [Training & testing details]() +- [Intended use & ethics]() +- [Environmental impacts]() + +--- + +## Anatomy of an ML-BOM + +In CycloneDX, a model is considered a `component` where general best practices for providing information such as component identification, metadata, provenance, pedigree, etc. should be followed as documented in the [CycloneDX Authoritative Guide to SBOM](https://cyclonedx.org/guides/OWASP_CycloneDX-Authoritative-Guide-to-SBOM-en.pdf). + + +![Diagram: Anatomy of an ML-BOM](images/anatomy.svg) + +#### Describing models as components + + + +##### Stand-alone model files + + +##### Model repositories + + +--- + +## Model card + +CycloneDX + +### Model identifiers + +#### + + +--- + +### Model metadata + +
+\newpage +
diff --git a/ML-BOM/en/0x20-Object-Model.md b/ML-BOM/en/0x20-Object-Model.md deleted file mode 100644 index ce0ac4b..0000000 --- a/ML-BOM/en/0x20-Object-Model.md +++ /dev/null @@ -1,19 +0,0 @@ -# CycloneDX ML-BOM Object Model - -## Overview - -An ML-BOM makes use of many of the common, core elements of the CycloneDX schema as well as unique aspects specific to ML components, their architectures, metadata, training and other information used to gauge adherence to regulatory compliance. - -This section will include specifics of how ML-related information should be conveyed using both using the CycloneDX schema. - -## Object schema - -#### Common CycloneDX schema used for ML-BOM - -#### ML-BOM-specific schema - -TBD - -
-\newpage -
diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index 5221152..ad88b9a 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -5,18 +5,22 @@ The following resources may be useful to users and adopters of the CycloneDX sta #### Standards and regulatory references * [Ecma Technical Committee 54](https://tc54.org) + * [ECMA-424 BOM Specification](https://tc54.org/cyclonedx/) - Specification for describing software, hardware and data components, services, dependencies, composition, attestations, vulnerabilities, licenses, formulations and more. + * [ECMA-427 PURL Specification](https://ecma-international.org/publications-and-standards/standards/ecma-427/) + * [ECMA-428 Common Lifecycle Enumeration (CLE) specification](https://ecma-international.org/publications-and-standards/standards/ecma-428/) * [European Union's Cyber Resilience Act (EU CRA)](https://www.european-cyber-resilience-act.com/) * [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework) #### CycloneDX resources * [OWASP CycloneDX](https://cyclonedx.org/) -* OWASP CycloneDX [Tool Center](https://cyclonedx.org/tool-center/) -* OWASP CycloneDX [BOM Repository Server](https://github.com/CycloneDX/cyclonedx-bom-repo-server) + * OWASP CycloneDX [Authoritative Guide to SBOM](https://cyclonedx.org/guides/OWASP_CycloneDX-Authoritative-Guide-to-SBOM-en.pdf) + * [Tool Center](https://cyclonedx.org/tool-center/) + * [BOM Repository Server](https://github.com/CycloneDX/cyclonedx-bom-repo-server) * [OWASP Dependency-Track](https://dependencytrack.org/) * [OWASP Software Component Verification Standard (SCVS)](https://scvs.owasp.org/) * [SCVS BOM Maturity Model](https://scvs.owasp.org/bom-maturity-model/) -* Package-URL specification: [https://github.com/package-url/purl-spec/](https://github.com/package-url/purl-spec/) +* [Package-URL (PURL) Specification](https://github.com/package-url/purl-spec/) (GitHub) #### Referenced standards @@ -29,3 +33,7 @@ The following resources may be useful to users and adopters of the CycloneDX sta * [Huggingface](https://huggingface.co/) - an open-source platform and community for Artificial Intelligence (AI) and Machine Learning (ML). * [PyTorch](https://pytorch.org/) - an optimized tensor library and framework used for deep learning on GPUs and CPUs. * [TensorFlow](https://www.tensorflow.org/) - An end-to-end open source machine learning platform. + +#### Model references + +* Huggingface [microsoft/resnet-50](https://huggingface.co/microsoft/resnet-50/blob/main/README.md) diff --git a/ML-BOM/en/images/anatomy.svg b/ML-BOM/en/images/anatomy.svg new file mode 100644 index 0000000..493a161 --- /dev/null +++ b/ML-BOM/en/images/anatomy.svg @@ -0,0 +1 @@ +Componenttype = “machine-learning-model”Model CardModel ParametersDatasetsApproachArchitectureTaskInputsOutputsQuantitative AnalysisPerformanceMetricsGraphicsConsiderationsPerformanceTradeoffsUsersTechnicalLimitationsUse CasesEthicalConsiderationsFairnessAssessmentsEnvironmentalConsiderations \ No newline at end of file From 995666f57b8962c76efd288b95b069d876635f9e Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 12 Jan 2026 16:21:14 -0600 Subject: [PATCH 004/111] Create a guide for ML-BOM relative to CycloneDX v1.7 schema Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Best-Practices.md | 25 ++++++++++++++++++++++++- ML-BOM/en/images/anatomy.svg | 2 +- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Best-Practices.md b/ML-BOM/en/0x20-Design-Best-Practices.md index c03088f..e0a782a 100644 --- a/ML-BOM/en/0x20-Design-Best-Practices.md +++ b/ML-BOM/en/0x20-Design-Best-Practices.md @@ -32,7 +32,7 @@ In CycloneDX, a model is considered a `component` where general best practices f ![Diagram: Anatomy of an ML-BOM](images/anatomy.svg) -#### Describing models as components +### Describing models as components @@ -42,6 +42,29 @@ In CycloneDX, a model is considered a `component` where general best practices f ##### Model repositories +### Declaring datasets + +Using CycloneDX there are two methods to provide information on the datasets (e.g., ) used to train, test, and evaluate machine learning models. + +Specifically, the component `modelCard` object includes `modelParameters` which includes an array of `datasets` objects which can be of the following types: + +1. **In-line information**: provides in-line objects that provide for direct description of datasets and some of their typically cited attributes and characteristics. Typically, this method mirrors dataset information found in various model catalogs and provides a means for direct, simplified mapping to CycloneDX. + * *This method may be helpful if the datasets themselves are not public (i.e., directly referenceable), but informational details are.* +2. **Data component reference**: provides for the complete description of each dataset as its own CycloneDX component and referenced via its `bom-ref`. + * *This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information.* + +#### In-line information object model + + +##### Example + + +#### Data component references + + +##### Example + + --- ## Model card diff --git a/ML-BOM/en/images/anatomy.svg b/ML-BOM/en/images/anatomy.svg index 493a161..287bf81 100644 --- a/ML-BOM/en/images/anatomy.svg +++ b/ML-BOM/en/images/anatomy.svg @@ -1 +1 @@ -Componenttype = “machine-learning-model”Model CardModel ParametersDatasetsApproachArchitectureTaskInputsOutputsQuantitative AnalysisPerformanceMetricsGraphicsConsiderationsPerformanceTradeoffsUsersTechnicalLimitationsUse CasesEthicalConsiderationsFairnessAssessmentsEnvironmentalConsiderations \ No newline at end of file +4Componenttype = “machine-learning-model”Model CardModel ParametersDatasetsApproachArchitectureTaskInputsOutputsQuantitative AnalysisPerformanceMetricsGraphicsConsiderationsPerformanceTradeoffsUsersTechnicalLimitationsUse CasesEthicalConsiderationsFairnessAssessmentsEnvironmentalConsiderations \ No newline at end of file From 40817c0193fcca7c724e3df19b085decf78e5259 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 13 Jan 2026 14:58:05 -0600 Subject: [PATCH 005/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Best-Practices.md | 20 +- ML-BOM/en/0x90-Appendix-A_Glossary.md | 54 ++ ML-BOM/en/0x91-Appendix-B_References.md | 13 +- .../hf-model-repo-Qwen-7B-file-list.png | Bin 0 -> 148361 bytes .../en/images/ml-bom-metadata-component.svg | 601 ++++++++++++++++++ 5 files changed, 684 insertions(+), 4 deletions(-) create mode 100644 ML-BOM/en/images/hf-model-repo-Qwen-7B-file-list.png create mode 100644 ML-BOM/en/images/ml-bom-metadata-component.svg diff --git a/ML-BOM/en/0x20-Design-Best-Practices.md b/ML-BOM/en/0x20-Design-Best-Practices.md index e0a782a..d00eec9 100644 --- a/ML-BOM/en/0x20-Design-Best-Practices.md +++ b/ML-BOM/en/0x20-Design-Best-Practices.md @@ -34,17 +34,31 @@ In CycloneDX, a model is considered a `component` where general best practices f ### Describing models as components +A model should always be declared as a CycloneDX `component`. If the model itself is the subject of the BOM, then the BOM is considered an ML-BOM and the `component` representing it would be declared in the top-level BOM `metadata` object. +The object model's pseudo-schema would look something like this: +![](images/ml-bom-metadata-component.svg) -##### Stand-alone model files - +As you can see in the above example, the `component` has a `bom-ref` that is also a valid [Package URL (PURL)](https://github.com/package-url/purl-spec) for a ["Qwen-7B" model hosted in a Huggingface model repository](https://huggingface.co/Qwen/Qwen-7B). When a valid `purl` value is available for a model, it is recommended that it also be used as its component's `bom-ref`. ##### Model repositories +When referencing an ML model, it typically means you are typically referencing a model repository since the models themselves often require multiple files in order to be used for actual training or inference with their pre-trained tensor data. Model repositories also include metadata, often referred to as model card data, that describe the model's use cases, design, architecture along with descriptive information on functional techniques that may be unique to the model functional processing. + +For example, a Natural Language Processing (NLP) model which uses a common Transformer architecture in Huggingface may include not only tensor data files (e.g., `.safetensors` or `.gguf`) files, but also files that describe the token mappings, tokenizer configurations, prompt templates as well as default (functional) model configurations used to initialize model implementations and more. + +###### Qwen/Qwen-7B + +Using the Qwen/Qwen-7B model in Huggingface as an discrete example (https://huggingface.co/Qwen/Qwen-7B), we see complete list of files that make up the "model" in its repository: + + + +##### Stand-alone model files + ### Declaring datasets -Using CycloneDX there are two methods to provide information on the datasets (e.g., ) used to train, test, and evaluate machine learning models. +Using CycloneDX there are two methods to provide information on the datasets used to train, test, and evaluate machine learning models. Specifically, the component `modelCard` object includes `modelParameters` which includes an array of `datasets` objects which can be of the following types: diff --git a/ML-BOM/en/0x90-Appendix-A_Glossary.md b/ML-BOM/en/0x90-Appendix-A_Glossary.md index c469e50..d995362 100644 --- a/ML-BOM/en/0x90-Appendix-A_Glossary.md +++ b/ML-BOM/en/0x90-Appendix-A_Glossary.md @@ -2,6 +2,60 @@ - TBD +--- + +### Model formats + +#### Huggingface Safetensors + +Safetensors addresses security and efficiency limitations present in traditional Python serialization approaches like pickle, used by PyTorch. The format uses a restricted deserialization process to prevent code execution vulnerabilities. + +A safetensors file contains: + +* A metadata section saved in JSON format. This section contains information about all tensors in the model, such as their shape, data type, and name. It can optionally also contain custom metadata. +* A section for the tensor data. + +[1] https://huggingface.co/blog/ngxson/common-ai-model-formats + +#### GGUF + +GGUF was initially developed for the llama.cpp project. GGUF is a binary format designed for fast model loading and saving, and for ease of readability. Models are typically developed using PyTorch or another framework, and then converted to GGUF for use with GGML. + +A GGUF file comprises: + +* A metadata section organized in key-value pairs. This section contains information about the model, such as its architecture, version, and hyperparameters. +* A section for tensor metadata. This section includes details about the tensors in the model, such as their shape, data type, and name. +* Finally, a section containing the tensor data itself. + +[1] https://huggingface.co/blog/ngxson/common-ai-model-formats + +--- + +#### ONNX + +Open Neural Network Exchange (ONNX) format offers a vendor-neutral representation of machine learning models. It is part of the ONNX ecosystem, which includes tools and libraries for interoperability between different frameworks like PyTorch, TensorFlow, and MXNet. + +ONNX models are saved in a single file with the .onnx extension. Unlike GGUF or Safetensors, ONNX contains not only the model's tensors and metadata, but also the model's computation graph. [1] + +The internal contents of an ONNX file generally include: + +* **Model Metadata**: General information about the model, such as its name, a human-readable documentation string, the name and version of the tool that generated it (e.g., PyTorch), the ONNX Intermediate Representation (IR) version it uses, and the version of the operator sets it relies on. +* **Computation Graph**: This is the core of the ONNX model, representing the data flow and operations required for computation. It is structured as a topologically sorted, directed acyclic graph (DAG). The graph itself contains: + * **Nodes**: Each node represents a specific operation (e.g., convolution, activation function, matrix multiplication). + * **Inputs and Outputs**: These define the data (tensors) that enter and leave the overall graph, including information on their data types and shapes. + * **Initializers** (Weights/Parameters): These are named, constant tensor values that define the pre-trained weights and biases of the model. When an initializer has the same name as a graph input, it serves as a default value. + * **Value Information**: Optional information regarding the types and shapes of intermediate values (tensors) produced and consumed within the graph. + +* **Operator Sets** (Opsets): A model specifies the collection of operator sets (identified by a domain and version number) that define the available operators and their semantics (behavior). This ensures consistency across different runtimes. +* **Functions** (Optional): An optional list of functions local to the model, which are custom operators defined as a sub-graph of other, more primitive ONNX operators. [2, 3, 4, 5, 6] + +[1] https://huggingface.co/blog/ngxson/common-ai-model-formats +[2] https://www.tutorialspoint.com/onnx/onnx-file-format.htm +[3] https://www.ultralytics.com/glossary/onnx-open-neural-network-exchange +[4] https://nx.docs.scailable.net/for-data-scientists/about-onnx +[5] https://mmapped.blog/posts/37-onnx-intro +[6] https://github.com/onnx/onnx/blob/main/docs/IR.md +
\newpage
diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index ad88b9a..e3d29c6 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -36,4 +36,15 @@ The following resources may be useful to users and adopters of the CycloneDX sta #### Model references -* Huggingface [microsoft/resnet-50](https://huggingface.co/microsoft/resnet-50/blob/main/README.md) +* Huggingface + * [microsoft/resnet-50](https://huggingface.co/microsoft/resnet-50/blob/main/README.md) - single `model.safetensors`, `pytorch_model.bin` file. + * [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) - multiple `*.safetensors` files with `model.safetensors.index.json` index. + +* Kaggle + * [mistral-ai/ministral-3](https://www.kaggle.com/models/mistral-ai/ministral-3) - multiple files that appear much like they would in a HF repo. Multiple `*.safetensors` files with `model.safetensors.index.json` index. + +* ONNX (`.onnx`) - Note most ONNX models have transitioned to and are now registered in Huggingface, but are downloaded from linked GitHub repository files not within the HF repo. itself. + * Huggingface + * [onnx/DenseNet-121-9](https://huggingface.co/onnx/DenseNet-121-9/tree/main) - `densenet-9.onnx` + * GitHub (https://github.com/onnx/models/tree/main/validated/) + * [vision/object_detection_segmentation/tiny-yolov2/model](https://github.com/onnx/models/tree/main/validated/vision/object_detection_segmentation/tiny-yolov2/model) - `tinyyolov2-7.onnx` diff --git a/ML-BOM/en/images/hf-model-repo-Qwen-7B-file-list.png b/ML-BOM/en/images/hf-model-repo-Qwen-7B-file-list.png new file mode 100644 index 0000000000000000000000000000000000000000..d55ffa5407b3572ab56c17e80bd224242e960834 GIT binary patch literal 148361 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

MD`&P&P#OXB@(!os1QwaZS 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%0A$G4v%==o9x+!Q#hxrkO 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 +metadata: object+component: component+...<bom>: object+metadata: <metadata>+...component: object+bom-ref: "pkg:huggingface/Qwen/Qwen-7B@main"+type: "machine-learning-model"+... From 71cc342e4b92cafaa1c0434b75b402f8ab366077 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 13 Jan 2026 15:35:37 -0600 Subject: [PATCH 006/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- .../en/images/ml-bom-metadata-component.svg | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/ML-BOM/en/images/ml-bom-metadata-component.svg b/ML-BOM/en/images/ml-bom-metadata-component.svg index 66e5262..98e2778 100644 --- a/ML-BOM/en/images/ml-bom-metadata-component.svg +++ b/ML-BOM/en/images/ml-bom-metadata-component.svg @@ -1,7 +1,7 @@ metadata: object...<bom>: object...component: object7B@main"7B@ef3c..."... From e37961b63caec8b9944ade146bfb2fc4d066db9f Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 13 Jan 2026 15:37:08 -0600 Subject: [PATCH 007/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Best-Practices.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Best-Practices.md b/ML-BOM/en/0x20-Design-Best-Practices.md index d00eec9..8dadec9 100644 --- a/ML-BOM/en/0x20-Design-Best-Practices.md +++ b/ML-BOM/en/0x20-Design-Best-Practices.md @@ -41,13 +41,13 @@ The object model's pseudo-schema would look something like this: As you can see in the above example, the `component` has a `bom-ref` that is also a valid [Package URL (PURL)](https://github.com/package-url/purl-spec) for a ["Qwen-7B" model hosted in a Huggingface model repository](https://huggingface.co/Qwen/Qwen-7B). When a valid `purl` value is available for a model, it is recommended that it also be used as its component's `bom-ref`. -##### Model repositories +#### Model repositories as components -When referencing an ML model, it typically means you are typically referencing a model repository since the models themselves often require multiple files in order to be used for actual training or inference with their pre-trained tensor data. Model repositories also include metadata, often referred to as model card data, that describe the model's use cases, design, architecture along with descriptive information on functional techniques that may be unique to the model functional processing. +When referencing an ML model as a component, it typically means you are typically referencing a model repository since the models themselves often require multiple files in order to be used for actual training or inference with their pre-trained tensor data. Model repositories also include metadata, often referred to as model card data, that describe the model's use cases, design, architecture along with descriptive information on functional techniques that may be unique to the model functional processing. For example, a Natural Language Processing (NLP) model which uses a common Transformer architecture in Huggingface may include not only tensor data files (e.g., `.safetensors` or `.gguf`) files, but also files that describe the token mappings, tokenizer configurations, prompt templates as well as default (functional) model configurations used to initialize model implementations and more. -###### Qwen/Qwen-7B +###### Example: Qwen/Qwen-7B Using the Qwen/Qwen-7B model in Huggingface as an discrete example (https://huggingface.co/Qwen/Qwen-7B), we see complete list of files that make up the "model" in its repository: From e1baa550b2d4c21a2001eb9d600cb04fc0297799 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 13 Jan 2026 15:49:36 -0600 Subject: [PATCH 008/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Best-Practices.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ML-BOM/en/0x20-Design-Best-Practices.md b/ML-BOM/en/0x20-Design-Best-Practices.md index 8dadec9..dd7bfb7 100644 --- a/ML-BOM/en/0x20-Design-Best-Practices.md +++ b/ML-BOM/en/0x20-Design-Best-Practices.md @@ -53,8 +53,14 @@ Using the Qwen/Qwen-7B model in Huggingface as an discrete example (https://hugg -##### Stand-alone model files +However, much like a software "package" the model repository would be referenced as a single CycloneDX component. That is why the [Package URL specification](https://github.com/package-url/purl-spec) has a [Huggingface package type](https://github.com/package-url/purl-spec/blob/main/types/huggingface-definition.json) defined. +If you wish to detail the files, you can do so by creating a `component` entry for each and declaring it in the BOM's `components` array and describe this relationship (via `bom-ref` links) as a CycloneDX assembly within the BOM's `compositions` array. + +### Identifying a specific model quantization + +TODO TODO TODO +- need to discuss with PURL community as this is not exampled for Huggingface package type. ### Declaring datasets From 388a0172e7655dcb9eb5458ab1b0c06848c05de6 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 14 Jan 2026 15:06:01 -0600 Subject: [PATCH 009/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Best-Practices.md | 121 ++++++++++++++++++------ ML-BOM/en/0x85-Appendix-1-Examples.md | 96 +++++++++++++++++++ ML-BOM/en/0x90-Appendix-A_Glossary.md | 32 ++++++- ML-BOM/en/0x91-Appendix-B_References.md | 28 ++++-- 4 files changed, 239 insertions(+), 38 deletions(-) create mode 100644 ML-BOM/en/0x85-Appendix-1-Examples.md diff --git a/ML-BOM/en/0x20-Design-Best-Practices.md b/ML-BOM/en/0x20-Design-Best-Practices.md index dd7bfb7..c369909 100644 --- a/ML-BOM/en/0x20-Design-Best-Practices.md +++ b/ML-BOM/en/0x20-Design-Best-Practices.md @@ -12,16 +12,20 @@ The [Core Concepts](0x15-Core-Concepts.md#key-components-of-an-ml-bom) listed in For convenience, here are links to the specific sections for each of those informational areas: -- [Model representation](#model-representation) -- [Model identifiers](#model-identifiers) -- [Model metadata](#model-metadata) -- [Model architecture]() -- [Datasets]() -- [Tokenizers and prompt templates]() -- [Hardware, software & frameworks]() -- [Training & testing details]() -- [Intended use & ethics]() -- [Environmental impacts]() +- [Anatomy of an ML-BOM](#anatomy-of-an-ml-bom) + - [Describing models as components](#describing-models-as-components) + - [Model repositories as components](#model-repositories-as-components) + - [Model identifiers](#model-identifiers) + +- [Model card](#model-card) + - [Model metadata](#model-metadata) + - [Model architecture]() + - [Datasets]() + - [Tokenizers and prompt templates]() + - [Hardware, software & frameworks]() + - [Training & testing details]() + - [Intended use & ethics]() + - [Environmental impacts]() --- @@ -39,15 +43,22 @@ A model should always be declared as a CycloneDX `component`. If the model itse The object model's pseudo-schema would look something like this: ![](images/ml-bom-metadata-component.svg) +#### Model identifier(s) + As you can see in the above example, the `component` has a `bom-ref` that is also a valid [Package URL (PURL)](https://github.com/package-url/purl-spec) for a ["Qwen-7B" model hosted in a Huggingface model repository](https://huggingface.co/Qwen/Qwen-7B). When a valid `purl` value is available for a model, it is recommended that it also be used as its component's `bom-ref`. +##### Identifying a specific model quantization + +> [!TODO] +> Need to discuss with PURL community as this is not exampled for Huggingface package type. + #### Model repositories as components When referencing an ML model as a component, it typically means you are typically referencing a model repository since the models themselves often require multiple files in order to be used for actual training or inference with their pre-trained tensor data. Model repositories also include metadata, often referred to as model card data, that describe the model's use cases, design, architecture along with descriptive information on functional techniques that may be unique to the model functional processing. -For example, a Natural Language Processing (NLP) model which uses a common Transformer architecture in Huggingface may include not only tensor data files (e.g., `.safetensors` or `.gguf`) files, but also files that describe the token mappings, tokenizer configurations, prompt templates as well as default (functional) model configurations used to initialize model implementations and more. +For example, a [Natural Language Processing (NLP)](0x90-Appendix-A_Glossary.md#natural-language-processing-nlp) model which uses a common [Transformer architecture](0x90-Appendix-A_Glossary.md#transformer) in Huggingface may include not only tensor data files (e.g., `.safetensors` or `.gguf`) files, but also files that describe the token mappings, tokenizer configurations, prompt templates as well as default (functional) model configurations used to initialize model implementations and more. -###### Example: Qwen/Qwen-7B +###### Example: Qwen/Qwen-7B model Using the Qwen/Qwen-7B model in Huggingface as an discrete example (https://huggingface.co/Qwen/Qwen-7B), we see complete list of files that make up the "model" in its repository: @@ -55,12 +66,78 @@ Using the Qwen/Qwen-7B model in Huggingface as an discrete example (https://hugg However, much like a software "package" the model repository would be referenced as a single CycloneDX component. That is why the [Package URL specification](https://github.com/package-url/purl-spec) has a [Huggingface package type](https://github.com/package-url/purl-spec/blob/main/types/huggingface-definition.json) defined. -If you wish to detail the files, you can do so by creating a `component` entry for each and declaring it in the BOM's `components` array and describe this relationship (via `bom-ref` links) as a CycloneDX assembly within the BOM's `compositions` array. +###### Example: CycloneDX for the Qwen-7B model + +The following example shows how the Qwen-7B model (repository) from Huggingface would appear in a CycloneDX ML-BOM as its subject component. + +``` +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.7", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "purl": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "group": "Qwen" + "manufacturer": "Alibaba Cloud", + "supplier": "Hugging Face", + "name": "Qwen/Qwen-7B", + "version": "ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "description": "Qwen-7B is a Transformer-based large language model, which is pretrained on a large volume of data, including web texts, books, codes, etc.", + "externalReferences": [ + { + "type": "vcs", + "url": "https://huggingface.co/" + }, + { + "type": "model-card", + "url": "https://huggingface.co/Qwen/Qwen-7B" + } + ], + "modelCard": { + ... + } + } + ] +} + +``` + +###### Notes + +- **version** - Models are not always versioned in the way software packages are (e.g., using `semver` format); however, within repositories such as Huggingface, the version is determined by its version control system's *commit hash*, *tag*, or *branch*. In the above example, the model's commit hash is used.
+- **model card** - *The CycloneDX representation of model card information will be detailed in a subsequent section.* +
In the above example, we show how to use an `externalReference` to provide a link to the model's Hugging Face model card which is comprised of mostly unstructured information in the form of a markdown file (i.e., README.md). + + +#### Describing a model repository as a CycloneDX assembly + +If you wish to detail the files that are include in the model's repository, you can do so by creating a `component` entry for each and declaring it in the BOM's `components` array and describe this relationship (via `bom-ref` links) as a CycloneDX assembly within the BOM's `compositions` array. + +###### Example + +> [!TODO] +> Need graphic and JSON + +``` +TBD +``` -### Identifying a specific model quantization +--- + +## Model card -TODO TODO TODO -- need to discuss with PURL community as this is not exampled for Huggingface package type. +This section provides a guide to best practices when filling out information for a CycloneDX `component` which has the type `machine-learning-model`. + + +### Model metadata + + +--- ### Declaring datasets @@ -84,18 +161,6 @@ Specifically, the component `modelCard` object includes `modelParameters` which ##### Example - ---- - -## Model card - -CycloneDX - -### Model identifiers - -#### - - --- ### Model metadata diff --git a/ML-BOM/en/0x85-Appendix-1-Examples.md b/ML-BOM/en/0x85-Appendix-1-Examples.md new file mode 100644 index 0000000..2f22819 --- /dev/null +++ b/ML-BOM/en/0x85-Appendix-1-Examples.md @@ -0,0 +1,96 @@ +# Appendix 1: Examples + +## Full ML-BOM example + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.7", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "component-a", + "type": "machine-learning-model", + "publisher": "Acme Inc", + "group": "CompVis", + "name": "stable-diffusion", + "version": "1.4", + "description": "Stable Diffusion is a latent text-to-image diffusion model capable of generating photo-realistic images given any text input. For more information about how Stable Diffusion functions, please have a look at \uD83E\uDD17's Stable Diffusion with \uD83E\uDDE8Diffusers blog.", + "modelCard": { + "modelParameters": { + "approach": { + "type": "supervised" + }, + "task": "task goes here", + "architectureFamily": "the architecture family goes here", + "modelArchitecture": "The architecture of the model.", + "datasets": [ + { + "type": "dataset", + "name": "Training Data", + "contents": { + "url": "https://example.com/path/to/dataset" + }, + "classification": "public" + } + ], + "inputs": [ + { + "format": "string" + } + ], + "outputs": [ + { + "format": "byte[]" + } + ] + }, + "quantitativeAnalysis": { + "performanceMetrics": [ + { + "type": "The type of performance metric", + "value": "The value of the performance metric", + "slice": "The name of the slice this metric was computed on. By default, assume this metric is not sliced", + "confidenceInterval": { + "lowerBound": "The lower bound of the confidence interval", + "upperBound": "The upper bound of the confidence interval" + } + } + ] + }, + "considerations": { + "users": [ + "Who are the intended users of the model?" + ], + "useCases": [ + "Who are the intended users of the model?" + ], + "technicalLimitations": [ + "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?" + ], + "performanceTradeoffs": [ + "What are the known tradeoffs in accuracy/performance of the model?" + ], + "ethicalConsiderations": [ + { + "name": "The name of the risk", + "mitigationStrategy": "Strategy used to address this risk" + } + ], + "fairnessAssessments": [ + { + "groupAtRisk": "The groups or individuals at risk of being systematically disadvantaged by the model", + "benefits": "Expected benefits to the identified groups", + "harms": "Expected harms to the identified groups", + "mitigationStrategy": "With respect to the benefits and harms outlined, please describe any mitigation strategy implemented." + } + ] + } + } + } + ] +} + +``` \ No newline at end of file diff --git a/ML-BOM/en/0x90-Appendix-A_Glossary.md b/ML-BOM/en/0x90-Appendix-A_Glossary.md index d995362..041d62c 100644 --- a/ML-BOM/en/0x90-Appendix-A_Glossary.md +++ b/ML-BOM/en/0x90-Appendix-A_Glossary.md @@ -1,6 +1,32 @@ # Appendix A: Glossary -- TBD +##### Tensor + +In machine learning, the term tensor typically refers to data organized in a multidimensional array (M-way array), informally referred to as a "data tensor". Relational observations and concepts, established via ML model training of text, images, movies, sounds, and more can be stored in these "data tensors", and further analyzed either by artificial neural networks or tensor methods. [1] + +[1] [Wikipedia - Tensor (machine learning)](https://en.wikipedia.org/wiki/Tensor_(machine_learning)) + +--- + +##### Transformer + +Transformers are a type of neural network architecture that transforms or changes an input sequence into an output sequence. They do this by learning context and tracking relationships between sequence components. [1] + +The transformer's neural network architecture takes input data converts it to numerical representations called tokens, and each token is converted into a vector via lookup from an embedding table. At each layer of the neural network, each token is then contextualized within the scope of the context window with other (unmasked) tokens via a parallel multi-head attention mechanism, allowing the signal for key tokens to be amplified and less important tokens to be diminished. After one or many iterations through the neural network, the output tokens can then be converted back into consumable output. [2] + +[1] [AWS - What are transformers in artificial intelligence?](https://aws.amazon.com/what-is/transformers-in-artificial-intelligence/) +[2] [Wikipedia - Transformer (deep learning)](https://en.wikipedia.org/wiki/Transformer_(deep_learning)) + +--- + +##### Natural Language Processing (NLP) + +is the processing of natural language information by a computer. NLP is a subfield of computer science and is closely associated with artificial intelligence. NLP is also related to information retrieval, knowledge representation, computational linguistics, and linguistics more broadly. + +Major processing tasks in an NLP system include: speech recognition, text classification, natural language understanding, and natural language generation. [1] + +[1] [Wikipedia - Natural language processing](https://en.wikipedia.org/wiki/Natural_language_processing) + --- @@ -17,9 +43,9 @@ A safetensors file contains: [1] https://huggingface.co/blog/ngxson/common-ai-model-formats -#### GGUF +#### GGUF (GPT-Generated Unified Format) -GGUF was initially developed for the llama.cpp project. GGUF is a binary format designed for fast model loading and saving, and for ease of readability. Models are typically developed using PyTorch or another framework, and then converted to GGUF for use with GGML. +GGUF is an acronym for GPT-Generated Unified Format and was initially developed for the llama.cpp project. GGUF is a binary format designed for fast model loading and saving, and for ease of readability. Models are typically developed using PyTorch or another framework, and then converted to GGUF for use with GGML. A GGUF file comprises: diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index e3d29c6..ef5cb76 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -9,6 +9,11 @@ The following resources may be useful to users and adopters of the CycloneDX sta * [ECMA-427 PURL Specification](https://ecma-international.org/publications-and-standards/standards/ecma-427/) * [ECMA-428 Common Lifecycle Enumeration (CLE) specification](https://ecma-international.org/publications-and-standards/standards/ecma-428/) * [European Union's Cyber Resilience Act (EU CRA)](https://www.european-cyber-resilience-act.com/) + * [Cyber Resilience Act (CRA) | The Final Text](https://www.european-cyber-resilience-act.com/Cyber_Resilience_Act_Articles.html) + * [Article 53: Obligations for Providers of General-Purpose AI Models](https://artificialintelligenceact.eu/article/53/) + * [Annex XI: Technical Documentation Referred to in Article 53(1), Point (a) – Technical Documentation for Providers of General-Purpose AI Models](https://artificialintelligenceact.eu/annex/11/) + * [Explanatory Notice and Template for the Public Summary of Training Content for general-purpose AI models](https://digital-strategy.ec.europa.eu/en/library/explanatory-notice-and-template-public-summary-training-content-general-purpose-ai-models) + * [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework) #### CycloneDX resources @@ -36,15 +41,24 @@ The following resources may be useful to users and adopters of the CycloneDX sta #### Model references -* Huggingface +##### Huggingface + +Huggingface model (repositories) typically support the `.safetensors` Huggingface format; however, within the same repository alternative formats are often found such as PyTorch (`.bin`, `.pt`), GGUF (`.gguf`) + * [microsoft/resnet-50](https://huggingface.co/microsoft/resnet-50/blob/main/README.md) - single `model.safetensors`, `pytorch_model.bin` file. * [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) - multiple `*.safetensors` files with `model.safetensors.index.json` index. -* Kaggle +##### Kaggle + * [mistral-ai/ministral-3](https://www.kaggle.com/models/mistral-ai/ministral-3) - multiple files that appear much like they would in a HF repo. Multiple `*.safetensors` files with `model.safetensors.index.json` index. -* ONNX (`.onnx`) - Note most ONNX models have transitioned to and are now registered in Huggingface, but are downloaded from linked GitHub repository files not within the HF repo. itself. - * Huggingface - * [onnx/DenseNet-121-9](https://huggingface.co/onnx/DenseNet-121-9/tree/main) - `densenet-9.onnx` - * GitHub (https://github.com/onnx/models/tree/main/validated/) - * [vision/object_detection_segmentation/tiny-yolov2/model](https://github.com/onnx/models/tree/main/validated/vision/object_detection_segmentation/tiny-yolov2/model) - `tinyyolov2-7.onnx` +##### ONNX + +ONNX models are typically single file format ending with the `.onnx` extension. + +Note: Most ONNX models have transitioned to and are now registered in Huggingface, but are downloaded from linked GitHub repository files not within the HF repo. itself. + +* Huggingface + * [onnx/DenseNet-121-9](https://huggingface.co/onnx/DenseNet-121-9/tree/main) - `densenet-9.onnx` +* GitHub (https://github.com/onnx/models/tree/main/validated/) + * [vision/object_detection_segmentation/tiny-yolov2/model](https://github.com/onnx/models/tree/main/validated/vision/object_detection_segmentation/tiny-yolov2/model) - `tinyyolov2-7.onnx` From 036c797b6d8a3f56a5b875ffd8788f54d92d16c8 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 14 Jan 2026 15:49:48 -0600 Subject: [PATCH 010/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ...ctices.md => 0x20-Design-Model-General.md} | 50 +------ ML-BOM/en/0x21-Design-Model-Card.md | 130 ++++++++++++++++++ 2 files changed, 134 insertions(+), 46 deletions(-) rename ML-BOM/en/{0x20-Design-Best-Practices.md => 0x20-Design-Model-General.md} (79%) create mode 100644 ML-BOM/en/0x21-Design-Model-Card.md diff --git a/ML-BOM/en/0x20-Design-Best-Practices.md b/ML-BOM/en/0x20-Design-Model-General.md similarity index 79% rename from ML-BOM/en/0x20-Design-Best-Practices.md rename to ML-BOM/en/0x20-Design-Model-General.md index c369909..af625c3 100644 --- a/ML-BOM/en/0x20-Design-Best-Practices.md +++ b/ML-BOM/en/0x20-Design-Model-General.md @@ -17,16 +17,6 @@ For convenience, here are links to the specific sections for each of those infor - [Model repositories as components](#model-repositories-as-components) - [Model identifiers](#model-identifiers) -- [Model card](#model-card) - - [Model metadata](#model-metadata) - - [Model architecture]() - - [Datasets]() - - [Tokenizers and prompt templates]() - - [Hardware, software & frameworks]() - - [Training & testing details]() - - [Intended use & ethics]() - - [Environmental impacts]() - --- ## Anatomy of an ML-BOM @@ -36,6 +26,10 @@ In CycloneDX, a model is considered a `component` where general best practices f ![Diagram: Anatomy of an ML-BOM](images/anatomy.svg) +--- + +## Model Component + ### Describing models as components A model should always be declared as a CycloneDX `component`. If the model itself is the subject of the BOM, then the BOM is considered an ML-BOM and the `component` representing it would be declared in the top-level BOM `metadata` object. @@ -129,42 +123,6 @@ TBD --- -## Model card - -This section provides a guide to best practices when filling out information for a CycloneDX `component` which has the type `machine-learning-model`. - - -### Model metadata - - ---- - -### Declaring datasets - -Using CycloneDX there are two methods to provide information on the datasets used to train, test, and evaluate machine learning models. - -Specifically, the component `modelCard` object includes `modelParameters` which includes an array of `datasets` objects which can be of the following types: - -1. **In-line information**: provides in-line objects that provide for direct description of datasets and some of their typically cited attributes and characteristics. Typically, this method mirrors dataset information found in various model catalogs and provides a means for direct, simplified mapping to CycloneDX. - * *This method may be helpful if the datasets themselves are not public (i.e., directly referenceable), but informational details are.* -2. **Data component reference**: provides for the complete description of each dataset as its own CycloneDX component and referenced via its `bom-ref`. - * *This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information.* - -#### In-line information object model - - -##### Example - - -#### Data component references - - -##### Example - ---- - -### Model metadata -

\newpage
diff --git a/ML-BOM/en/0x21-Design-Model-Card.md b/ML-BOM/en/0x21-Design-Model-Card.md new file mode 100644 index 0000000..1e408b0 --- /dev/null +++ b/ML-BOM/en/0x21-Design-Model-Card.md @@ -0,0 +1,130 @@ +# ML-BOM Design and Best Practices + +## Model card + +This section describes the design and best practices when providing information for a CycloneDX `modelCard` in an ML-BOM as part of the model's CycloneDX `component` definition. + +For convenience, here are links to the specific sections for each of those informational areas: + +- [Model metadata](#model-metadata) +- [Model architecture]() +- [Datasets]() +- [Tokenizers and prompt templates]() +- [Hardware, software & frameworks]() +- [Training & testing details]() +- [Intended use & ethics]() +- [Environmental impacts]() + +###### Example: CycloneDX Model Card for the Qwen-7B model + +Again, we continue to showcase the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model from Hugging Face. You may follow the link to its home page in Hugging Face which should show you its [README.md]() file which contains some structured, but mostly unstructured model card information to see how it is translated to CycloneDX objects and schema. + +```json +"modelCard": { + "modelParameters": { + "approach": { + "type": "supervised" + }, + "task": "task goes here", + "architectureFamily": "the architecture family goes here", + "modelArchitecture": "The architecture of the model.", + "datasets": [ + { + "type": "dataset", + "name": "Training Data", + "contents": { + "url": "https://example.com/path/to/dataset" + }, + "classification": "public" + } + ], + "inputs": [ + { + "format": "string" + } + ], + "outputs": [ + { + "format": "byte[]" + } + ] +}, +"quantitativeAnalysis": { + "performanceMetrics": [ + { + "type": "The type of performance metric", + "value": "The value of the performance metric", + "slice": "The name of the slice this metric was computed on. By default, assume this metric is not sliced", + "confidenceInterval": { + "lowerBound": "The lower bound of the confidence interval", + "upperBound": "The upper bound of the confidence interval" + } + } + ] +}, +"considerations": { + "users": [ + "Who are the intended users of the model?" + ], + "useCases": [ + "Who are the intended users of the model?" + ], + "technicalLimitations": [ + "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?" + ], + "performanceTradeoffs": [ + "What are the known tradeoffs in accuracy/performance of the model?" + ], + "ethicalConsiderations": [ + { + "name": "The name of the risk", + "mitigationStrategy": "Strategy used to address this risk" + } + ], + "fairnessAssessments": [ + { + "groupAtRisk": "The groups or individuals at risk of being systematically disadvantaged by the model", + "benefits": "Expected benefits to the identified groups", + "harms": "Expected harms to the identified groups", + "mitigationStrategy": "With respect to the benefits and harms outlined, please describe any mitigation strategy implemented." + } + ] + } +} +``` + + +### Model metadata + + +--- + +### Declaring datasets + +Using CycloneDX there are two methods to provide information on the datasets used to train, test, and evaluate machine learning models. + +Specifically, the component `modelCard` object includes `modelParameters` which includes an array of `datasets` objects which can be of the following types: + +1. **In-line information**: provides in-line objects that provide for direct description of datasets and some of their typically cited attributes and characteristics. Typically, this method mirrors dataset information found in various model catalogs and provides a means for direct, simplified mapping to CycloneDX. + * *This method may be helpful if the datasets themselves are not public (i.e., directly referenceable), but informational details are.* +2. **Data component reference**: provides for the complete description of each dataset as its own CycloneDX component and referenced via its `bom-ref`. + * *This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information.* + +#### In-line information object model + + +##### Example + + +#### Data component references + + +##### Example + +--- + +### Model metadata + +
+\newpage +
From 4d1d23c45231275c9b0376f9d3fd5cbf34a52ac5 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 14 Jan 2026 16:43:21 -0600 Subject: [PATCH 011/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-General.md | 5 +++ ...Card.md => 0x21-Design-Model-Card copy.md} | 44 +++++++++++++++---- ML-BOM/en/0x29-Design-Other.md | 21 +++++++++ 3 files changed, 62 insertions(+), 8 deletions(-) rename ML-BOM/en/{0x21-Design-Model-Card.md => 0x21-Design-Model-Card copy.md} (87%) create mode 100644 ML-BOM/en/0x29-Design-Other.md diff --git a/ML-BOM/en/0x20-Design-Model-General.md b/ML-BOM/en/0x20-Design-Model-General.md index af625c3..6535eb5 100644 --- a/ML-BOM/en/0x20-Design-Model-General.md +++ b/ML-BOM/en/0x20-Design-Model-General.md @@ -16,6 +16,7 @@ For convenience, here are links to the specific sections for each of those infor - [Describing models as components](#describing-models-as-components) - [Model repositories as components](#model-repositories-as-components) - [Model identifiers](#model-identifiers) + - [Model metadata](#model-metadata) --- @@ -123,6 +124,10 @@ TBD --- +# Model metadata + +--- +
\newpage
diff --git a/ML-BOM/en/0x21-Design-Model-Card.md b/ML-BOM/en/0x21-Design-Model-Card copy.md similarity index 87% rename from ML-BOM/en/0x21-Design-Model-Card.md rename to ML-BOM/en/0x21-Design-Model-Card copy.md index 1e408b0..225f21f 100644 --- a/ML-BOM/en/0x21-Design-Model-Card.md +++ b/ML-BOM/en/0x21-Design-Model-Card copy.md @@ -6,14 +6,42 @@ This section describes the design and best practices when providing information For convenience, here are links to the specific sections for each of those informational areas: -- [Model metadata](#model-metadata) -- [Model architecture]() -- [Datasets]() -- [Tokenizers and prompt templates]() -- [Hardware, software & frameworks]() -- [Training & testing details]() -- [Intended use & ethics]() -- [Environmental impacts]() +- [Model parameters]() + - [Model architecture]() + - [Approach & tasks]() + - [Datasets]() + - [Inputs & Outputs]() + - [Tokenizers and prompt templates]() + +- [Quantitative analysis]() + - [Performance metrics & graphics]() + +- [Considerations]() + - [Users & use cases]() + - [Technical limitations]() + - [Performance tradeoffs]() + - [Fairness assessments]() + - [Intended use & ethics]() + - [Environmental impacts]() + +- [Other] + - [Hardware, software & frameworks]() + - [Training & testing details]() + + + +### Model parameters + + +#### Model architecture + +--- + +### Quantitative Analysis + + +--- + ###### Example: CycloneDX Model Card for the Qwen-7B model diff --git a/ML-BOM/en/0x29-Design-Other.md b/ML-BOM/en/0x29-Design-Other.md new file mode 100644 index 0000000..11da965 --- /dev/null +++ b/ML-BOM/en/0x29-Design-Other.md @@ -0,0 +1,21 @@ +# ML-BOM Design and Best Practices + +## Other + +This section describes the design and best practices when providing information for a CycloneDX `modelCard` in an ML-BOM as part of the model's CycloneDX `component` definition. + +For convenience, here are links to the specific sections for each of those informational areas: + +- [Model metadata](#model-metadata) +- [Model architecture]() +- [Datasets]() +- [Tokenizers and prompt templates]() +- [Hardware, software & frameworks]() +- [Training & testing details]() +- [Intended use & ethics]() +- [Environmental impacts]() + + +
+\newpage +
From c1d79acc6ded690a5bdd37e93c2dff55f3265d1a Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 15 Jan 2026 10:32:29 -0600 Subject: [PATCH 012/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ...d => 0x20-Design-Model-Component-Metadata.md} | 16 +++++++++++----- ...el-Card copy.md => 0x21-Design-Model-Card.md} | 4 +--- 2 files changed, 12 insertions(+), 8 deletions(-) rename ML-BOM/en/{0x20-Design-Model-General.md => 0x20-Design-Model-Component-Metadata.md} (77%) rename ML-BOM/en/{0x21-Design-Model-Card copy.md => 0x21-Design-Model-Card.md} (99%) diff --git a/ML-BOM/en/0x20-Design-Model-General.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md similarity index 77% rename from ML-BOM/en/0x20-Design-Model-General.md rename to ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 6535eb5..91097a9 100644 --- a/ML-BOM/en/0x20-Design-Model-General.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -40,7 +40,9 @@ The object model's pseudo-schema would look something like this: #### Model identifier(s) -As you can see in the above example, the `component` has a `bom-ref` that is also a valid [Package URL (PURL)](https://github.com/package-url/purl-spec) for a ["Qwen-7B" model hosted in a Huggingface model repository](https://huggingface.co/Qwen/Qwen-7B). When a valid `purl` value is available for a model, it is recommended that it also be used as its component's `bom-ref`. +As you can see in the above example, the `component` has a `bom-ref` that is also a valid [Package URL (PURL)](https://github.com/package-url/purl-spec) for a ["Qwen-7B" model hosted in a Huggingface model repository](https://huggingface.co/Qwen/Qwen-7B) using the [Hugging Face PURL type](https://github.com/package-url/purl-spec/blob/main/types-doc/huggingface-definition.md). When a valid `purl` value is available for a model, it is recommended that it also be used as its component's `bom-ref`. + +If a model is hosted in a GitHub, it can also be referenced using a [GitHub Package URL](https://github.com/package-url/purl-spec/blob/main/types-doc/github-definition.md). For example, the ONNX vision model: [tiny-yolov2](https://github.com/onnx/models/tree/main/validated/vision/object_detection_segmentation/tiny-yolov2/model) (`tinyyolov2-7.onnx`) would have a PURL like `"pkg:github/onnx/models/validated/vision/object_detection_segmentation/tiny-yolov2/model@4c46cd0"`. ##### Identifying a specific model quantization @@ -102,11 +104,15 @@ The following example shows how the Qwen-7B model (repository) from Huggingface ``` -###### Notes +###### Field notes -- **version** - Models are not always versioned in the way software packages are (e.g., using `semver` format); however, within repositories such as Huggingface, the version is determined by its version control system's *commit hash*, *tag*, or *branch*. In the above example, the model's commit hash is used.
-- **model card** - *The CycloneDX representation of model card information will be detailed in a subsequent section.* -
In the above example, we show how to use an `externalReference` to provide a link to the model's Hugging Face model card which is comprised of mostly unstructured information in the form of a markdown file (i.e., README.md). +- **purl** - The Package URL (PURL) follows the [Huggingface package type](https://github.com/package-url/purl-spec/blob/main/types/huggingface-definition.json) using a commit hash. +- **name** - The model name reflects how the model is identified under Hugging Face using the `/` format. +- **version** - Models are not always versioned in the way software packages are (e.g., using `semver` format); however, within repositories such as Huggingface, the version is determined by its version control system's *commit hash*, *tag*, or *branch*. In the above example, the model's commit hash is used and matches the `purl` value.
+- **manufacturer** - The name of the company which built the Qwen model. +- **externalReferences** + - **vcs** - Provides a link to the version control system (i.e., the model provider aka. `supplier`). In this example, this is Hugging Face and affirms the associated PURL identifier. + - **model-card** - Provides a link to the model's Hugging Face model card which is comprised of mostly unstructured information in the form of a markdown file (i.e., README.md).
*The CycloneDX representation of model card information will be detailed in a subsequent section.* #### Describing a model repository as a CycloneDX assembly diff --git a/ML-BOM/en/0x21-Design-Model-Card copy.md b/ML-BOM/en/0x21-Design-Model-Card.md similarity index 99% rename from ML-BOM/en/0x21-Design-Model-Card copy.md rename to ML-BOM/en/0x21-Design-Model-Card.md index 225f21f..e1eacf1 100644 --- a/ML-BOM/en/0x21-Design-Model-Card copy.md +++ b/ML-BOM/en/0x21-Design-Model-Card.md @@ -24,12 +24,10 @@ For convenience, here are links to the specific sections for each of those infor - [Intended use & ethics]() - [Environmental impacts]() -- [Other] +- [Other]() - [Hardware, software & frameworks]() - [Training & testing details]() - - ### Model parameters From 3e8347f0a92802bf01d05661ed15466698ebba84 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 15 Jan 2026 15:06:23 -0600 Subject: [PATCH 013/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- .../0x20-Design-Model-Component-Metadata.md | 115 ++++++++++++++---- ML-BOM/en/0x85-Appendix-1-Examples.md | 2 +- ML-BOM/en/0x91-Appendix-B_References.md | 53 ++++---- 3 files changed, 124 insertions(+), 46 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 91097a9..b3131f7 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -38,11 +38,66 @@ A model should always be declared as a CycloneDX `component`. If the model itse The object model's pseudo-schema would look something like this: ![](images/ml-bom-metadata-component.svg) +##### Example: JSON equivalent + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.7", + "serialNumber": "urn:uuid:ec45525e-516c-4405-9de3-4fbdaef7f09a", + "version": 1, + "metadata": + { + "component": + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + ... + } + ... + } + ... +} +``` + #### Model identifier(s) As you can see in the above example, the `component` has a `bom-ref` that is also a valid [Package URL (PURL)](https://github.com/package-url/purl-spec) for a ["Qwen-7B" model hosted in a Huggingface model repository](https://huggingface.co/Qwen/Qwen-7B) using the [Hugging Face PURL type](https://github.com/package-url/purl-spec/blob/main/types-doc/huggingface-definition.md). When a valid `purl` value is available for a model, it is recommended that it also be used as its component's `bom-ref`. -If a model is hosted in a GitHub, it can also be referenced using a [GitHub Package URL](https://github.com/package-url/purl-spec/blob/main/types-doc/github-definition.md). For example, the ONNX vision model: [tiny-yolov2](https://github.com/onnx/models/tree/main/validated/vision/object_detection_segmentation/tiny-yolov2/model) (`tinyyolov2-7.onnx`) would have a PURL like `"pkg:github/onnx/models/validated/vision/object_detection_segmentation/tiny-yolov2/model@4c46cd0"`. +If the model being described by an ML-BOM is hosted in a GitHub, it can also be referenced using a [GitHub Package URL](https://github.com/package-url/purl-spec/blob/main/types-doc/github-definition.md). For example, the ONNX vision model: [tiny-yolov2](https://github.com/onnx/models/tree/main/validated/vision/object_detection_segmentation/tiny-yolov2/model) would have a `github` PURL type. + +###### Example: JSON for model component with GitHub PURL + +```json +"component": +{ + "type": "machine-learning-model", + "bom-ref": "pkg:github/onnx/models/validated/vision/object_detection_segmentation/tiny-yolov2/model@4c46cd0", + ... +} +``` + +##### Adding domain-specific identifiers + +Organizations that produce BOMs for hardware or software components they produce may have a plurality of domain-specific identifiers for the same component. In these cases, it is best practice to register (reserve) an official namespace for these domains with the [CycloneDX Property Taxonomy]() which is the authoritative source of official namespaces used in CycloneDX `properties`. + +###### Example: + +The following example shows how a registered names for a fictional company ACME which registered the namespace `acme` could provide a property to identify one of its internal ML models. + +```json +"component": { + "properties": [ + { + "name": 'acme:research:model:llm:id', + "value": "MODEL-ID-12345-INTERNAL" + }, + ... + ], + ... +} +``` ##### Identifying a specific model quantization @@ -51,30 +106,25 @@ If a model is hosted in a GitHub, it can also be referenced using a [GitHub Pack #### Model repositories as components -When referencing an ML model as a component, it typically means you are typically referencing a model repository since the models themselves often require multiple files in order to be used for actual training or inference with their pre-trained tensor data. Model repositories also include metadata, often referred to as model card data, that describe the model's use cases, design, architecture along with descriptive information on functional techniques that may be unique to the model functional processing. - -For example, a [Natural Language Processing (NLP)](0x90-Appendix-A_Glossary.md#natural-language-processing-nlp) model which uses a common [Transformer architecture](0x90-Appendix-A_Glossary.md#transformer) in Huggingface may include not only tensor data files (e.g., `.safetensors` or `.gguf`) files, but also files that describe the token mappings, tokenizer configurations, prompt templates as well as default (functional) model configurations used to initialize model implementations and more. - -###### Example: Qwen/Qwen-7B model +When referencing an ML model as a component, it typically means you are referencing a **model repository** comprised of metadata and a set of files (e.g., pre-trained tensor data in various formats, model configurations, tokenizers, tokenizer configurations, prompt templates, Python code, etc.) which would be selectively used with various, compatible AI or ML applications and frameworks. -Using the Qwen/Qwen-7B model in Huggingface as an discrete example (https://huggingface.co/Qwen/Qwen-7B), we see complete list of files that make up the "model" in its repository: +If possible, these model repositories should be treated like a software "package" in a Software Bill-of-Materiels (SBOM) when declaring it as a `machine-learning-model` type of CycloneDX component. - + -However, much like a software "package" the model repository would be referenced as a single CycloneDX component. That is why the [Package URL specification](https://github.com/package-url/purl-spec) has a [Huggingface package type](https://github.com/package-url/purl-spec/blob/main/types/huggingface-definition.json) defined. +###### Example: CycloneDX for the Qwen-7B model repository -###### Example: CycloneDX for the Qwen-7B model +The following example shows how the Qwen-7B model repository would be declared as a CycloneDX `component` of type `machine-learning-model`s in a CycloneDX ML-BOM as its subject component. -The following example shows how the Qwen-7B model (repository) from Huggingface would appear in a CycloneDX ML-BOM as its subject component. +Since the the model repository is hosted in Hugging Face Hub, the [Huggingface package type](https://github.com/package-url/purl-spec/blob/main/types/huggingface-definition.json) may be used [Package URL specification](https://github.com/package-url/purl-spec) to identify the model. -``` +```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.7", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "components": [ + ... + "metadata": + { + "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", @@ -96,24 +146,32 @@ The following example shows how the Qwen-7B model (repository) from Huggingface } ], "modelCard": { - ... + ... } } - ] + } } ``` ###### Field notes +- **bom-ref** - Since a PURL is available, it can also be used as the `bom-ref`. - **purl** - The Package URL (PURL) follows the [Huggingface package type](https://github.com/package-url/purl-spec/blob/main/types/huggingface-definition.json) using a commit hash. +- **manufacturer** - The name of the company which built the Qwen model. +- **group** - In this example, we chose to include the optional group field to acknowledge the specific model repository is part of the Qwen family of models. - **name** - The model name reflects how the model is identified under Hugging Face using the `/` format. - **version** - Models are not always versioned in the way software packages are (e.g., using `semver` format); however, within repositories such as Huggingface, the version is determined by its version control system's *commit hash*, *tag*, or *branch*. In the above example, the model's commit hash is used and matches the `purl` value.
-- **manufacturer** - The name of the company which built the Qwen model. -- **externalReferences** +- **externalReferences** - Used to provide unambiguous links to component's model repository and originating model card. - **vcs** - Provides a link to the version control system (i.e., the model provider aka. `supplier`). In this example, this is Hugging Face and affirms the associated PURL identifier. - **model-card** - Provides a link to the model's Hugging Face model card which is comprised of mostly unstructured information in the form of a markdown file (i.e., README.md).
*The CycloneDX representation of model card information will be detailed in a subsequent section.* +###### Example: Qwen/Qwen-7B model + +If we look inside the repository for the [Qwen/Qwen-7B model in Huggingface](https://huggingface.co/Qwen/Qwen-7B), we see the complete list of files that make up the "model" in its repository: + + + #### Describing a model repository as a CycloneDX assembly @@ -124,8 +182,19 @@ If you wish to detail the files that are include in the model's repository, you > [!TODO] > Need graphic and JSON -``` -TBD +```json +"components": [ + { + "type": "file", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "purl": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "group": "Qwen" + "manufacturer": "Alibaba Cloud", + "supplier": "Hugging Face", + "name": "Qwen/Qwen-7B", + "version": "ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "description": "Qwen-7B" + } ``` --- diff --git a/ML-BOM/en/0x85-Appendix-1-Examples.md b/ML-BOM/en/0x85-Appendix-1-Examples.md index 2f22819..0edb2e7 100644 --- a/ML-BOM/en/0x85-Appendix-1-Examples.md +++ b/ML-BOM/en/0x85-Appendix-1-Examples.md @@ -7,7 +7,7 @@ "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", "bomFormat": "CycloneDX", "specVersion": "1.7", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "serialNumber": "urn:uuid:ec45525e-516c-4405-9de3-4fbdaef7f09a", "version": 1, "components": [ { diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index ef5cb76..07dfaf3 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -1,46 +1,55 @@ # Appendix B: References -The following resources may be useful to users and adopters of the CycloneDX standard and its ML-BOM profile: +This appendix includes references to resources, standards, technologies and models used within this guide. + +#### CycloneDX references and resources + +* [OWASP Foundation](https://owasp.org/) + * [OWASP Dependency-Track](https://dependencytrack.org/) + * [OWASP Software Component Verification Standard (SCVS)](https://scvs.owasp.org/) + * [SCVS BOM Maturity Model](https://scvs.owasp.org/bom-maturity-model/) +* [OWASP CycloneDX](https://cyclonedx.org/) + * [CycloneDX Authoritative Guide to SBOM](https://cyclonedx.org/guides/OWASP_CycloneDX-Authoritative-Guide-to-SBOM-en.pdf) + * [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy) + * [CycloneDX Tool Center](https://cyclonedx.org/tool-center/) + * [CycloneDX BOM Repository Server](https://github.com/CycloneDX/cyclonedx-bom-repo-server) +* [Package-URL (PURL) Specification](https://github.com/package-url/purl-spec/) (GitHub) + +--- #### Standards and regulatory references -* [Ecma Technical Committee 54](https://tc54.org) - * [ECMA-424 BOM Specification](https://tc54.org/cyclonedx/) - Specification for describing software, hardware and data components, services, dependencies, composition, attestations, vulnerabilities, licenses, formulations and more. - * [ECMA-427 PURL Specification](https://ecma-international.org/publications-and-standards/standards/ecma-427/) - * [ECMA-428 Common Lifecycle Enumeration (CLE) specification](https://ecma-international.org/publications-and-standards/standards/ecma-428/) +* [Ecma Technical Committee 54 - Software and System Transparency.](https://tc54.org) - Standardizing core data formats, APIs, and algorithms that advance software and system transparency. + * [ECMA-424 BOM Specification](https://tc54.org/cyclonedx/) - The CycloneDX specification for describing software, hardware and data components, services, dependencies, composition, attestations, vulnerabilities, licenses, formulations and more. + * [ECMA-427 PURL Specification](https://ecma-international.org/publications-and-standards/standards/ecma-427/) - This standard defines the Package-URL (PURL) syntax for identifying software packages independently from their ecosystem or distribution channel + * [ECMA-428 Common Lifecycle Enumeration (CLE) specification](https://ecma-international.org/publications-and-standards/standards/ecma-428/) - The CLE provides a standardized format for communicating software component lifecycle events in a machine-readable format. * [European Union's Cyber Resilience Act (EU CRA)](https://www.european-cyber-resilience-act.com/) * [Cyber Resilience Act (CRA) | The Final Text](https://www.european-cyber-resilience-act.com/Cyber_Resilience_Act_Articles.html) * [Article 53: Obligations for Providers of General-Purpose AI Models](https://artificialintelligenceact.eu/article/53/) * [Annex XI: Technical Documentation Referred to in Article 53(1), Point (a) – Technical Documentation for Providers of General-Purpose AI Models](https://artificialintelligenceact.eu/annex/11/) * [Explanatory Notice and Template for the Public Summary of Training Content for general-purpose AI models](https://digital-strategy.ec.europa.eu/en/library/explanatory-notice-and-template-public-summary-training-content-general-purpose-ai-models) - +* [Linux Foundation projects](https://www.linuxfoundation.org/projects) + * [System Package Data Exchange™ (SPDX®)](https://spdx.dev/) + * [SPDX License IDs](https://spdx.dev/ids/) + * [SPDX License List](https://spdx.org/licenses/) * [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework) -#### CycloneDX resources - -* [OWASP CycloneDX](https://cyclonedx.org/) - * OWASP CycloneDX [Authoritative Guide to SBOM](https://cyclonedx.org/guides/OWASP_CycloneDX-Authoritative-Guide-to-SBOM-en.pdf) - * [Tool Center](https://cyclonedx.org/tool-center/) - * [BOM Repository Server](https://github.com/CycloneDX/cyclonedx-bom-repo-server) -* [OWASP Dependency-Track](https://dependencytrack.org/) -* [OWASP Software Component Verification Standard (SCVS)](https://scvs.owasp.org/) - * [SCVS BOM Maturity Model](https://scvs.owasp.org/bom-maturity-model/) -* [Package-URL (PURL) Specification](https://github.com/package-url/purl-spec/) (GitHub) - -#### Referenced standards - -* [OpenChain](https://www.openchainproject.org/) -* [SPDX License IDs](https://spdx.dev/ids/) -* [SPDX License List](https://spdx.org/licenses/) +--- #### Technology references +The following AI or ML technologies were referenced in discussion and/or examples in this guide: + * [Huggingface](https://huggingface.co/) - an open-source platform and community for Artificial Intelligence (AI) and Machine Learning (ML). * [PyTorch](https://pytorch.org/) - an optimized tensor library and framework used for deep learning on GPUs and CPUs. * [TensorFlow](https://www.tensorflow.org/) - An end-to-end open source machine learning platform. +--- + #### Model references +The following ML models were referenced in discussion and/or examples in this guide: + ##### Huggingface Huggingface model (repositories) typically support the `.safetensors` Huggingface format; however, within the same repository alternative formats are often found such as PyTorch (`.bin`, `.pt`), GGUF (`.gguf`) From 27f6ed005cc3614dd3191b52ca148a8541695c1d Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 15 Jan 2026 15:28:37 -0600 Subject: [PATCH 014/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- .../0x20-Design-Model-Component-Metadata.md | 116 +++++++++--------- 1 file changed, 61 insertions(+), 55 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index b3131f7..0c1711b 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -61,60 +61,15 @@ The object model's pseudo-schema would look something like this: } ``` -#### Model identifier(s) - -As you can see in the above example, the `component` has a `bom-ref` that is also a valid [Package URL (PURL)](https://github.com/package-url/purl-spec) for a ["Qwen-7B" model hosted in a Huggingface model repository](https://huggingface.co/Qwen/Qwen-7B) using the [Hugging Face PURL type](https://github.com/package-url/purl-spec/blob/main/types-doc/huggingface-definition.md). When a valid `purl` value is available for a model, it is recommended that it also be used as its component's `bom-ref`. - -If the model being described by an ML-BOM is hosted in a GitHub, it can also be referenced using a [GitHub Package URL](https://github.com/package-url/purl-spec/blob/main/types-doc/github-definition.md). For example, the ONNX vision model: [tiny-yolov2](https://github.com/onnx/models/tree/main/validated/vision/object_detection_segmentation/tiny-yolov2/model) would have a `github` PURL type. - -###### Example: JSON for model component with GitHub PURL - -```json -"component": -{ - "type": "machine-learning-model", - "bom-ref": "pkg:github/onnx/models/validated/vision/object_detection_segmentation/tiny-yolov2/model@4c46cd0", - ... -} -``` - -##### Adding domain-specific identifiers - -Organizations that produce BOMs for hardware or software components they produce may have a plurality of domain-specific identifiers for the same component. In these cases, it is best practice to register (reserve) an official namespace for these domains with the [CycloneDX Property Taxonomy]() which is the authoritative source of official namespaces used in CycloneDX `properties`. - -###### Example: - -The following example shows how a registered names for a fictional company ACME which registered the namespace `acme` could provide a property to identify one of its internal ML models. - -```json -"component": { - "properties": [ - { - "name": 'acme:research:model:llm:id', - "value": "MODEL-ID-12345-INTERNAL" - }, - ... - ], - ... -} -``` - -##### Identifying a specific model quantization - -> [!TODO] -> Need to discuss with PURL community as this is not exampled for Huggingface package type. - #### Model repositories as components When referencing an ML model as a component, it typically means you are referencing a **model repository** comprised of metadata and a set of files (e.g., pre-trained tensor data in various formats, model configurations, tokenizers, tokenizer configurations, prompt templates, Python code, etc.) which would be selectively used with various, compatible AI or ML applications and frameworks. -If possible, these model repositories should be treated like a software "package" in a Software Bill-of-Materiels (SBOM) when declaring it as a `machine-learning-model` type of CycloneDX component. - - +If possible, these model repositories should be treated like a software "package" in a Software Bill-of-Materiels (SBOM) when declaring it as a `machine-learning-model` type of CycloneDX component. ###### Example: CycloneDX for the Qwen-7B model repository -The following example shows how the Qwen-7B model repository would be declared as a CycloneDX `component` of type `machine-learning-model`s in a CycloneDX ML-BOM as its subject component. +The following example shows how the Qwen-7B model repository would be declared as a CycloneDX `component` of type `machine-learning-model` in a CycloneDX ML-BOM as its subject component. Since the the model repository is hosted in Hugging Face Hub, the [Huggingface package type](https://github.com/package-url/purl-spec/blob/main/types/huggingface-definition.json) may be used [Package URL specification](https://github.com/package-url/purl-spec) to identify the model. @@ -154,7 +109,9 @@ Since the the model repository is hosted in Hugging Face Hub, the [Huggingface p ``` -###### Field notes +###### Discussion of model fields and metadata + +This section provides best practice guidance on how the component fields were filled out for this example. - **bom-ref** - Since a PURL is available, it can also be used as the `bom-ref`. - **purl** - The Package URL (PURL) follows the [Huggingface package type](https://github.com/package-url/purl-spec/blob/main/types/huggingface-definition.json) using a commit hash. @@ -166,21 +123,70 @@ Since the the model repository is hosted in Hugging Face Hub, the [Huggingface p - **vcs** - Provides a link to the version control system (i.e., the model provider aka. `supplier`). In this example, this is Hugging Face and affirms the associated PURL identifier. - **model-card** - Provides a link to the model's Hugging Face model card which is comprised of mostly unstructured information in the form of a markdown file (i.e., README.md).
*The CycloneDX representation of model card information will be detailed in a subsequent section.* -###### Example: Qwen/Qwen-7B model -If we look inside the repository for the [Qwen/Qwen-7B model in Huggingface](https://huggingface.co/Qwen/Qwen-7B), we see the complete list of files that make up the "model" in its repository: - +#### Model identifier(s) + +As you can see in the above example, the `component` has a `bom-ref` that is also a valid [Package URL (PURL)](https://github.com/package-url/purl-spec) for a ["Qwen-7B" model hosted in a Huggingface model repository](https://huggingface.co/Qwen/Qwen-7B) using the [Hugging Face PURL type](https://github.com/package-url/purl-spec/blob/main/types-doc/huggingface-definition.md). When a valid `purl` value is available for a model, it is recommended that it also be used as its component's `bom-ref`. + +If the model being described by an ML-BOM is instead hosted in a GitHub repository, it can also be referenced using a [GitHub Package URL](https://github.com/package-url/purl-spec/blob/main/types-doc/github-definition.md). For example, the ONNX vision model: [tiny-yolov2](https://github.com/onnx/models/tree/main/validated/vision/object_detection_segmentation/tiny-yolov2/model) would have a `github` PURL type. +###### Example: JSON for model component with GitHub PURL + +```json +"component": +{ + "type": "machine-learning-model", + "bom-ref": "pkg:github/onnx/models/validated/vision/object_detection_segmentation/tiny-yolov2/model@4c46cd0", + ... +} +``` + +##### Adding domain-specific identifiers + +Organizations that produce BOMs for hardware or software components they produce may have a plurality of domain-specific identifiers for the same component. In these cases, it is best practice to register (reserve) an official namespace for these domains with the [CycloneDX Property Taxonomy]() which is the authoritative source of official namespaces used in CycloneDX `properties`. + +###### Example: + +The following example shows how a registered names for a fictional company ACME which registered the namespace `acme` could provide a property to identify one of its internal ML models. + +```json +"component": { + "properties": [ + { + "name": 'acme:research:model:llm:id', + "value": "MODEL-ID-12345-INTERNAL" + }, + ... + ], + ... +} +``` + +##### Identifying a specific model quantization + +> [!TODO] +> Need to discuss with PURL community as this is not exampled for Huggingface package type. + +--- #### Describing a model repository as a CycloneDX assembly -If you wish to detail the files that are include in the model's repository, you can do so by creating a `component` entry for each and declaring it in the BOM's `components` array and describe this relationship (via `bom-ref` links) as a CycloneDX assembly within the BOM's `compositions` array. +CycloneDX allows for declarations of software compositions (e.g., hardware products, software applications, packages, libraries, archives, etc.). + +In the case of a model repository like those hosted in Hugging Face, one can describe the files that comprise it as a composition with an ML-BOM. Specifically, it would be declared as an assembly type of composition. + +Specifically, a `component` entry would be created for each file and declared in the ML-BOM's `components` array then the assembly relationship would appear within the BOM's `compositions` array under `assemblies` using `bom-ref` links to each of the file components. + +###### Example: Qwen/Qwen-7B model + +If we look inside the repository for the [Qwen/Qwen-7B model in Huggingface](https://huggingface.co/Qwen/Qwen-7B), we see the complete list of files that make up the "model" in its repository: -###### Example + + +###### CycloneDX for the Qwen/Qwen-7B assembly > [!TODO] -> Need graphic and JSON ```json "components": [ @@ -199,7 +205,7 @@ If you wish to detail the files that are include in the model's repository, you --- -# Model metadata + --- From e83101ef4d9f6504e5ee43ac02417cf284fdf0bd Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 15 Jan 2026 16:53:01 -0600 Subject: [PATCH 015/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- .../0x20-Design-Model-Component-Metadata.md | 78 +++++++++++++++---- 1 file changed, 63 insertions(+), 15 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 0c1711b..f50c24c 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -186,26 +186,74 @@ If we look inside the repository for the [Qwen/Qwen-7B model in Huggingface](htt ###### CycloneDX for the Qwen/Qwen-7B assembly -> [!TODO] +The simplified JSON below shows how to declare a few of the files from the model repository's complete file list. + +Note that we use the Package URL syntax to provide the additional path (with the model repository or "package") to each individual file by appending it using the `#` hash symbol as a separator. Also, notice that the commit hash (identifier) varies per-file. ```json -"components": [ - { - "type": "file", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", - "purl": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", - "group": "Qwen" - "manufacturer": "Alibaba Cloud", - "supplier": "Hugging Face", - "name": "Qwen/Qwen-7B", - "version": "ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", - "description": "Qwen-7B" - } +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "components": [ + { + "type": "file", + "name": "config.json", + "description": "Model configuration file", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", + "purl": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", + ... + }, + { + "type": "file", + "name": "configuration_qwen.py", + "description": "Python 'QWenConfig' class implementation for the Qwen 7B model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", + "purl": "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", + ... + }, + { + "type": "data", + "name": "model-00001-of-00008.safetensors", + "description": "Model tensor data (01 of 08)", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", + "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", + ... + }, + { + "type": "data", + "name": "model-00002-of-00008.safetensors", + "description": "Model tensor data (01 of 08)", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", + "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", + ... + }, + ... + ], + ... +} ``` ---- - +These component files would then be used to create the assembly relationship. +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "composition": [ + { + "aggregate": "complete", + "components": [ + "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", + "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", + "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", + "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", + ... + ] + } + ], + ... +} +``` --- From 846c47ee2d91bc07da3c269a60b7f78f2f4c65a8 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 15 Jan 2026 16:53:32 -0600 Subject: [PATCH 016/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index f50c24c..4b49665 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -222,7 +222,7 @@ Note that we use the Package URL syntax to provide the additional path (with the { "type": "data", "name": "model-00002-of-00008.safetensors", - "description": "Model tensor data (01 of 08)", + "description": "Model tensor data (02 of 08)", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", ... From ac607a5d6b03d77d9224cc40a0231415f3f7a0b5 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 15 Jan 2026 16:56:03 -0600 Subject: [PATCH 017/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 4b49665..3ec2e76 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -198,7 +198,7 @@ Note that we use the Package URL syntax to provide the additional path (with the { "type": "file", "name": "config.json", - "description": "Model configuration file", + "description": "Model configuration file using the 'QWenLMHeadModel' model class in Hugging Face Transformers", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", "purl": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", ... @@ -206,7 +206,7 @@ Note that we use the Package URL syntax to provide the additional path (with the { "type": "file", "name": "configuration_qwen.py", - "description": "Python 'QWenConfig' class implementation for the Qwen 7B model", + "description": "Python 'QWenConfig' class implementation for the Qwen-7B model using Hugging Face Transformers", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", "purl": "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", ... From 57b5f39adcb974fd577ca283e26b87b44ebfa856 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 15 Jan 2026 17:41:12 -0600 Subject: [PATCH 018/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x21-Design-Model-Card.md | 67 +++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/ML-BOM/en/0x21-Design-Model-Card.md b/ML-BOM/en/0x21-Design-Model-Card.md index e1eacf1..3484f79 100644 --- a/ML-BOM/en/0x21-Design-Model-Card.md +++ b/ML-BOM/en/0x21-Design-Model-Card.md @@ -31,6 +31,73 @@ For convenience, here are links to the specific sections for each of those infor ### Model parameters +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "metadata": + { + "component": + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + ..., + "modelCard": { + "modelParameters": { + "task": "text-generation", + "architectureFamily": "transformer", + "modelArchitecture": "QWenLMHeadModel", + "approach": { + "type": "generative", + "motivations": ["text-generation", "conversational-ai"] + }, + "parameters": [ + { + "name": "total_parameters", + "value": "7 billion", + "description": "Total number of parameters in the model." + }, + { + "name": "context_length", + "value": "8192", + "description": "The maximum sequence length the model supports during pre-training and inference." + }, + { + "name": "vocab_size", + "value": "151936", + "description": "The size of the model's vocabulary." + }, + { + "name": "quantization_support", + "value": "4-bit, 8-bit", + "description": "Supported quantization levels for reduced memory usage, as seen in community variations like TheBloke/Qwen-7B-Chat-GPTQ." + } + ], + "inputs": [ + {"format": "string"} + ], + "outputs": [ + {"format": "string"} + ], + }, + "quantitativeAnalysis": { + "performanceMetrics": [ + { + "type": "benchmark_score", + "value": "specific benchmark score here", + "slice": "Specific benchmark name (e.g., MMLU, GSM8K)" + } + ] + }, + ... + } + } + } +} +``` +>![TODO] determine if we MUST also add "dependencies" to the composition to est. the relationship to the actual model repository. e.g., "dependencies": ["model-bom-ref"] + + #### Model architecture --- From a9665d7dcb351b968a9f455ebea4c6714a04cf16 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 16 Jan 2026 11:34:53 -0600 Subject: [PATCH 019/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- .../0x20-Design-Model-Component-Metadata.md | 95 ++++++++++--------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 3ec2e76..791e20a 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -176,7 +176,7 @@ CycloneDX allows for declarations of software compositions (e.g., hardware produ In the case of a model repository like those hosted in Hugging Face, one can describe the files that comprise it as a composition with an ML-BOM. Specifically, it would be declared as an assembly type of composition. -Specifically, a `component` entry would be created for each file and declared in the ML-BOM's `components` array then the assembly relationship would appear within the BOM's `compositions` array under `assemblies` using `bom-ref` links to each of the file components. +Specifically, a `component` entry would be created for each file and declared in the ML-BOM's `components` array hierarchically under the model's `component` then declare the assembly relationship within within the BOM's `compositions` array under `assemblies` by providing the `bom-ref` link to the model component that contains the hierarchy of the constituting (file) components within the model repository. ###### Example: Qwen/Qwen-7B model @@ -186,54 +186,63 @@ If we look inside the repository for the [Qwen/Qwen-7B model in Huggingface](htt ###### CycloneDX for the Qwen/Qwen-7B assembly -The simplified JSON below shows how to declare a few of the files from the model repository's complete file list. +The simplified JSON below shows how to declare a few of the files from the model repository's complete file list under the model's `component` declaration within the BOM's `metadata`. Note that we use the Package URL syntax to provide the additional path (with the model repository or "package") to each individual file by appending it using the `#` hash symbol as a separator. Also, notice that the commit hash (identifier) varies per-file. ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... - "components": [ - { - "type": "file", - "name": "config.json", - "description": "Model configuration file using the 'QWenLMHeadModel' model class in Hugging Face Transformers", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", - "purl": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", - ... - }, - { - "type": "file", - "name": "configuration_qwen.py", - "description": "Python 'QWenConfig' class implementation for the Qwen-7B model using Hugging Face Transformers", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", - "purl": "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", - ... - }, - { - "type": "data", - "name": "model-00001-of-00008.safetensors", - "description": "Model tensor data (01 of 08)", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", - "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", - ... - }, + ... + "metadata": { - "type": "data", - "name": "model-00002-of-00008.safetensors", - "description": "Model tensor data (02 of 08)", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", - "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", + "component": + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", ... - }, - ... - ], + "components": [ + { + "type": "file", + "name": "config.json", + "description": "Model configuration file using the 'QWenLMHeadModel' model class in Hugging Face Transformers", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", + "purl": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", + ... + }, + { + "type": "file", + "name": "configuration_qwen.py", + "description": "Python 'QWenConfig' class implementation for the Qwen-7B model using Hugging Face Transformers", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", + "purl": "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", + ... + }, + { + "type": "data", + "name": "model-00001-of-00008.safetensors", + "description": "Model tensor data (01 of 08)", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", + "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", + ... + }, + { + "type": "data", + "name": "model-00002-of-00008.safetensors", + "description": "Model tensor data (02 of 08)", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", + "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", + ... + }, + ... + ] + } + } ... } ``` -These component files would then be used to create the assembly relationship. +then the model component's new hierarchy of composing files would be described as an assembly composition as follows: ```json { @@ -242,12 +251,8 @@ These component files would then be used to create the assembly relationship. "composition": [ { "aggregate": "complete", - "components": [ - "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", - "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", - "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", - "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", - ... + "assemblies": [ + "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", ] } ], @@ -255,6 +260,10 @@ These component files would then be used to create the assembly relationship. } ``` +###### Discussion of composition fields + +- Note the composition `aggregate` value is assigned to be "complete" since all constituent files are known and declared in the ML-BOM as part of the model component's `components` hierarchy. + ---
From 609fd7abdb4dc535bb505890f4fdc3788fb9b572 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 16 Jan 2026 12:54:55 -0600 Subject: [PATCH 020/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- .../en/0x20-Design-Model-Component-Metadata.md | 6 +++--- ML-BOM/en/0x21-Design-Model-Card.md | 18 ++++++++++++++++++ ML-BOM/en/0x91-Appendix-B_References.md | 3 ++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 791e20a..f466f53 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -69,7 +69,7 @@ If possible, these model repositories should be treated like a software "package ###### Example: CycloneDX for the Qwen-7B model repository -The following example shows how the Qwen-7B model repository would be declared as a CycloneDX `component` of type `machine-learning-model` in a CycloneDX ML-BOM as its subject component. +The following example shows how the Hugging Face [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model repository would be declared as a CycloneDX `component` of type `machine-learning-model` in a CycloneDX ML-BOM as its subject component. Since the the model repository is hosted in Hugging Face Hub, the [Huggingface package type](https://github.com/package-url/purl-spec/blob/main/types/huggingface-definition.json) may be used [Package URL specification](https://github.com/package-url/purl-spec) to identify the model. @@ -178,7 +178,7 @@ In the case of a model repository like those hosted in Hugging Face, one can des Specifically, a `component` entry would be created for each file and declared in the ML-BOM's `components` array hierarchically under the model's `component` then declare the assembly relationship within within the BOM's `compositions` array under `assemblies` by providing the `bom-ref` link to the model component that contains the hierarchy of the constituting (file) components within the model repository. -###### Example: Qwen/Qwen-7B model +###### Example: Qwen/Qwen-7B model repository files If we look inside the repository for the [Qwen/Qwen-7B model in Huggingface](https://huggingface.co/Qwen/Qwen-7B), we see the complete list of files that make up the "model" in its repository: @@ -262,7 +262,7 @@ then the model component's new hierarchy of composing files would be described a ###### Discussion of composition fields -- Note the composition `aggregate` value is assigned to be "complete" since all constituent files are known and declared in the ML-BOM as part of the model component's `components` hierarchy. +- **aggregate** - Note the composition `aggregate` value is assigned to be "complete" since all constituent files are known and declared in the ML-BOM as part of the model component's `components` hierarchy. --- diff --git a/ML-BOM/en/0x21-Design-Model-Card.md b/ML-BOM/en/0x21-Design-Model-Card.md index 3484f79..ed79457 100644 --- a/ML-BOM/en/0x21-Design-Model-Card.md +++ b/ML-BOM/en/0x21-Design-Model-Card.md @@ -30,6 +30,19 @@ For convenience, here are links to the specific sections for each of those infor ### Model parameters +>![Note] add diagram of model parameters + +In general, model parameters describe values that are directly used to configure model processing applications and frameworks and their implementations of model architectures. For example, most models that appear in Hugging Face typically include configuration files for both the models and the tokenizers they are designed for use with the [Hugging Face Transformers](https://huggingface.co/docs/transformers/) library and its underlying use of the PyTorch framework. + +###### Example: CycloneDX for the Qwen-7B model repository + +The following example shows how the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model's parameters would be declared as a CycloneDX `modelCard`. + +As shown in the [Qwen/Qwen-7B model repository files](0x20-Design-Model-Component-Metadata.md#example-qwenqwen-7b-model-repository-files) example in the previous section, we see the model includes several configuration files including: + +- [config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/config.json) - which contains configuration parameters (as key-value pairs) used for initializing the model's implementation. +- [generation_config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/generation_config.json) - which contains model hyperparameters (as key-value pairs) and their suggested (default) values used for configuring the model for token generation (inference). + ```json { @@ -95,6 +108,11 @@ For convenience, here are links to the specific sections for each of those infor } } ``` + +###### Discussion of model card fields + +- **parameters** - + >![TODO] determine if we MUST also add "dependencies" to the composition to est. the relationship to the actual model repository. e.g., "dependencies": ["model-bom-ref"] diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index 07dfaf3..7e593f7 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -40,7 +40,8 @@ This appendix includes references to resources, standards, technologies and mode The following AI or ML technologies were referenced in discussion and/or examples in this guide: -* [Huggingface](https://huggingface.co/) - an open-source platform and community for Artificial Intelligence (AI) and Machine Learning (ML). +* [Hugging Face](https://huggingface.co/) - an open-source platform and community for Artificial Intelligence (AI) and Machine Learning (ML). + * [Hugging Face Transformers](https://huggingface.co/docs/transformers/) - a library that simplifies the training and inference of models that have a transformer architecture which uses PyTorch types and implementations "under-the-covers". * [PyTorch](https://pytorch.org/) - an optimized tensor library and framework used for deep learning on GPUs and CPUs. * [TensorFlow](https://www.tensorflow.org/) - An end-to-end open source machine learning platform. From 6d28bda2c5fbcbbc76ae9d62dd5666bca7aabb0f Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 16 Jan 2026 13:01:39 -0600 Subject: [PATCH 021/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x21-Design-Model-Card-Overview.md | 39 +++++++++++++++++++ ...d => 0x22-Design-Model-Card-Parameters.md} | 28 ------------- ...9-Design-Other.md => 0x40-Design-Other.md} | 0 ...le.md => 0x70-Use_Case_Software_Simple.md} | 0 4 files changed, 39 insertions(+), 28 deletions(-) create mode 100644 ML-BOM/en/0x21-Design-Model-Card-Overview.md rename ML-BOM/en/{0x21-Design-Model-Card.md => 0x22-Design-Model-Card-Parameters.md} (90%) rename ML-BOM/en/{0x29-Design-Other.md => 0x40-Design-Other.md} (100%) rename ML-BOM/en/{0x30-Use_Case_Software_Simple.md => 0x70-Use_Case_Software_Simple.md} (100%) diff --git a/ML-BOM/en/0x21-Design-Model-Card-Overview.md b/ML-BOM/en/0x21-Design-Model-Card-Overview.md new file mode 100644 index 0000000..ffaf45d --- /dev/null +++ b/ML-BOM/en/0x21-Design-Model-Card-Overview.md @@ -0,0 +1,39 @@ +# ML-BOM Design and Best Practices + +## Model card + +### Overview + +This section describes the design and best practices when providing information for a CycloneDX `modelCard` in an ML-BOM as part of the model's CycloneDX `component` definition. + +For convenience, here are links to the specific sections for each of those informational areas: + +>![TODO] add hyperlinks when done with all subsections + +- [Model parameters]() + - [Model architecture]() + - [Approach & tasks]() + - [Datasets]() + - [Inputs & Outputs]() + - [Tokenizers and prompt templates]() + +- [Quantitative analysis]() + - [Performance metrics & graphics]() + +- [Considerations]() + - [Users & use cases]() + - [Technical limitations]() + - [Performance tradeoffs]() + - [Fairness assessments]() + - [Intended use & ethics]() + - [Environmental impacts]() + +- [Other]() + - [Hardware, software & frameworks]() + - [Training & testing details]() + +### Model metadata + +
+\newpage +
diff --git a/ML-BOM/en/0x21-Design-Model-Card.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md similarity index 90% rename from ML-BOM/en/0x21-Design-Model-Card.md rename to ML-BOM/en/0x22-Design-Model-Card-Parameters.md index ed79457..22fd2ea 100644 --- a/ML-BOM/en/0x21-Design-Model-Card.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -1,33 +1,5 @@ # ML-BOM Design and Best Practices -## Model card - -This section describes the design and best practices when providing information for a CycloneDX `modelCard` in an ML-BOM as part of the model's CycloneDX `component` definition. - -For convenience, here are links to the specific sections for each of those informational areas: - -- [Model parameters]() - - [Model architecture]() - - [Approach & tasks]() - - [Datasets]() - - [Inputs & Outputs]() - - [Tokenizers and prompt templates]() - -- [Quantitative analysis]() - - [Performance metrics & graphics]() - -- [Considerations]() - - [Users & use cases]() - - [Technical limitations]() - - [Performance tradeoffs]() - - [Fairness assessments]() - - [Intended use & ethics]() - - [Environmental impacts]() - -- [Other]() - - [Hardware, software & frameworks]() - - [Training & testing details]() - ### Model parameters >![Note] add diagram of model parameters diff --git a/ML-BOM/en/0x29-Design-Other.md b/ML-BOM/en/0x40-Design-Other.md similarity index 100% rename from ML-BOM/en/0x29-Design-Other.md rename to ML-BOM/en/0x40-Design-Other.md diff --git a/ML-BOM/en/0x30-Use_Case_Software_Simple.md b/ML-BOM/en/0x70-Use_Case_Software_Simple.md similarity index 100% rename from ML-BOM/en/0x30-Use_Case_Software_Simple.md rename to ML-BOM/en/0x70-Use_Case_Software_Simple.md From beb3480df380894c263cfecb3bfc1c0c2722d148 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 16 Jan 2026 14:39:51 -0600 Subject: [PATCH 022/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- .../0x20-Design-Model-Component-Metadata.md | 8 + ML-BOM/en/0x21-Design-Model-Card-Overview.md | 4 + .../ml-anatomy-model-card-considerations.svg | 1 + .../ml-anatomy-model-card-parameters.svg | 1 + .../ml-anatomy-model-card-quant-analysis.svg | 1 + .../en/images/ml-bom-metadata-component.svg | 603 +----------------- 6 files changed, 16 insertions(+), 602 deletions(-) create mode 100644 ML-BOM/en/images/ml-anatomy-model-card-considerations.svg create mode 100644 ML-BOM/en/images/ml-anatomy-model-card-parameters.svg create mode 100644 ML-BOM/en/images/ml-anatomy-model-card-quant-analysis.svg diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index f466f53..226a160 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -224,6 +224,10 @@ Note that we use the Package URL syntax to provide the additional path (with the "description": "Model tensor data (01 of 08)", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", + "data": { + "type": "dataset", + ... + } ... }, { @@ -232,6 +236,10 @@ Note that we use the Package URL syntax to provide the additional path (with the "description": "Model tensor data (02 of 08)", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", + "data": { + "type": "dataset", + ... + } ... }, ... diff --git a/ML-BOM/en/0x21-Design-Model-Card-Overview.md b/ML-BOM/en/0x21-Design-Model-Card-Overview.md index ffaf45d..40f78a8 100644 --- a/ML-BOM/en/0x21-Design-Model-Card-Overview.md +++ b/ML-BOM/en/0x21-Design-Model-Card-Overview.md @@ -2,6 +2,10 @@ ## Model card +At the time of initial development, the CycloneDX model card schema was directly influenced by the [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) and specifically its [ModelCard fields](https://www.tensorflow.org/responsible_ai/model_card_toolkit/api_docs/python/model_card_toolkit/ModelCard) which lead to many assumptions model parameters and hyperparameters that perhaps do not translate well to more current ML Frameworks used for training and generation. + +Throughout the model card sections of this guide, we will show how to use the existing schema to encode information seen in model cards from a more current and robust perspective. + ### Overview This section describes the design and best practices when providing information for a CycloneDX `modelCard` in an ML-BOM as part of the model's CycloneDX `component` definition. diff --git a/ML-BOM/en/images/ml-anatomy-model-card-considerations.svg b/ML-BOM/en/images/ml-anatomy-model-card-considerations.svg new file mode 100644 index 0000000..2989d0e --- /dev/null +++ b/ML-BOM/en/images/ml-anatomy-model-card-considerations.svg @@ -0,0 +1 @@ +Model CardQuantitative AnalysisModel ParametersConsiderationsPerformanceTradeoffsUsersTechnicalLimitationsUse CasesEthicalConsiderationsFairnessAssessmentsEnvironmentalConsiderations \ No newline at end of file diff --git a/ML-BOM/en/images/ml-anatomy-model-card-parameters.svg b/ML-BOM/en/images/ml-anatomy-model-card-parameters.svg new file mode 100644 index 0000000..9f1cd1a --- /dev/null +++ b/ML-BOM/en/images/ml-anatomy-model-card-parameters.svg @@ -0,0 +1 @@ +Model CardModel ParametersDatasetsApproachArchitectureTaskInputsOutputsQuantitative AnalysisConsiderations \ No newline at end of file diff --git a/ML-BOM/en/images/ml-anatomy-model-card-quant-analysis.svg b/ML-BOM/en/images/ml-anatomy-model-card-quant-analysis.svg new file mode 100644 index 0000000..9bb0a4a --- /dev/null +++ b/ML-BOM/en/images/ml-anatomy-model-card-quant-analysis.svg @@ -0,0 +1 @@ +Model CardModel ParametersConsiderationsQuantitative AnalysisPerformanceMetricsGraphics \ No newline at end of file diff --git a/ML-BOM/en/images/ml-bom-metadata-component.svg b/ML-BOM/en/images/ml-bom-metadata-component.svg index 98e2778..1e74019 100644 --- a/ML-BOM/en/images/ml-bom-metadata-component.svg +++ b/ML-BOM/en/images/ml-bom-metadata-component.svg @@ -1,602 +1 @@ - -metadata: object+component: component+...<bom>: object+metadata: <metadata>+...component: object+bom-ref: "pkg:huggingface/Qwen/Qwen-7B@ef3c..."+type: "machine-learning-model"+... +metadata: object+component: <component>+...<bom>: object+metadata: <metadata>+...component: object+bom-ref: "pkg:huggingface/Qwen/Qwen-7B@ef3c..."+type: "machine-learning-model"+... \ No newline at end of file From a634c85bbd40bf956b3bbdc6d93474af2a61c720 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 19 Jan 2026 13:32:54 -0600 Subject: [PATCH 023/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x21-Design-Model-Card-Overview.md | 4 ++-- ML-BOM/en/0x22-Design-Model-Card-Parameters.md | 6 ++++-- ML-BOM/en/0x91-Appendix-B_References.md | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ML-BOM/en/0x21-Design-Model-Card-Overview.md b/ML-BOM/en/0x21-Design-Model-Card-Overview.md index 40f78a8..3bfd3e3 100644 --- a/ML-BOM/en/0x21-Design-Model-Card-Overview.md +++ b/ML-BOM/en/0x21-Design-Model-Card-Overview.md @@ -12,9 +12,9 @@ This section describes the design and best practices when providing information For convenience, here are links to the specific sections for each of those informational areas: ->![TODO] add hyperlinks when done with all subsections +>[!TODO] add hyperlinks when done with all subsections -- [Model parameters]() +- [Model parameters](0x22-Design-Model-Card-Parameters.md#model-parameters) - [Model architecture]() - [Approach & tasks]() - [Datasets]() diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index 22fd2ea..54f1374 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -1,11 +1,13 @@ # ML-BOM Design and Best Practices -### Model parameters +## Model parameters >![Note] add diagram of model parameters In general, model parameters describe values that are directly used to configure model processing applications and frameworks and their implementations of model architectures. For example, most models that appear in Hugging Face typically include configuration files for both the models and the tokenizers they are designed for use with the [Hugging Face Transformers](https://huggingface.co/docs/transformers/) library and its underlying use of the PyTorch framework. +> [!NOTE] The CycloneDX ModelParameters were initially based upon [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) (now archived) which defines [ModelParameters](https://www.tensorflow.org/responsible_ai/model_card_toolkit/api_docs/python/model_card_toolkit/ModelParameters) that include key-value maps for both inputs and outputs alongside an array of their types; these maps will be accomplished using CycloneDX properties and the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy) reserved namespace `cdx:ai-ml:parameter` and `cdx:ai-ml:hyperparameter` as needed. + ###### Example: CycloneDX for the Qwen-7B model repository The following example shows how the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model's parameters would be declared as a CycloneDX `modelCard`. @@ -85,7 +87,7 @@ As shown in the [Qwen/Qwen-7B model repository files](0x20-Design-Model-Componen - **parameters** - ->![TODO] determine if we MUST also add "dependencies" to the composition to est. the relationship to the actual model repository. e.g., "dependencies": ["model-bom-ref"] +>[!TODO] determine if we MUST also add "dependencies" to the composition to est. the relationship to the actual model repository. e.g., "dependencies": ["model-bom-ref"] #### Model architecture diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index 7e593f7..2af395d 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -44,6 +44,7 @@ The following AI or ML technologies were referenced in discussion and/or example * [Hugging Face Transformers](https://huggingface.co/docs/transformers/) - a library that simplifies the training and inference of models that have a transformer architecture which uses PyTorch types and implementations "under-the-covers". * [PyTorch](https://pytorch.org/) - an optimized tensor library and framework used for deep learning on GPUs and CPUs. * [TensorFlow](https://www.tensorflow.org/) - An end-to-end open source machine learning platform. + * [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) (archived) - streamlines and automates generation of Model Cards, machine learning documents that provide context and transparency into a model's development and performance. --- From fc3b50e94c08142f19c2da44042089111c5019d3 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 19 Jan 2026 14:15:31 -0600 Subject: [PATCH 024/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x21-Design-Model-Card-Overview.md | 8 +- .../en/0x22-Design-Model-Card-Parameters.md | 138 ++++++++++++++++-- 2 files changed, 130 insertions(+), 16 deletions(-) diff --git a/ML-BOM/en/0x21-Design-Model-Card-Overview.md b/ML-BOM/en/0x21-Design-Model-Card-Overview.md index 3bfd3e3..07603f2 100644 --- a/ML-BOM/en/0x21-Design-Model-Card-Overview.md +++ b/ML-BOM/en/0x21-Design-Model-Card-Overview.md @@ -2,7 +2,7 @@ ## Model card -At the time of initial development, the CycloneDX model card schema was directly influenced by the [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) and specifically its [ModelCard fields](https://www.tensorflow.org/responsible_ai/model_card_toolkit/api_docs/python/model_card_toolkit/ModelCard) which lead to many assumptions model parameters and hyperparameters that perhaps do not translate well to more current ML Frameworks used for training and generation. +A model card describes the intended uses of a machine learning model and potential limitations, including biases and ethical considerations. Model cards typically contain the training parameters, which datasets were used to train the model, performance metrics, and other relevant data useful for ML transparency. This object **SHOULD** be specified for any component of type machine-learning-model and must not be specified for other component types. Throughout the model card sections of this guide, we will show how to use the existing schema to encode information seen in model cards from a more current and robust perspective. @@ -36,7 +36,11 @@ For convenience, here are links to the specific sections for each of those infor - [Hardware, software & frameworks]() - [Training & testing details]() -### Model metadata +#### Design notes + +Please note that at the time of initial development, the CycloneDX model card schema was heavily influenced by [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) and specifically its [ModelCard fields](https://www.tensorflow.org/responsible_ai/model_card_toolkit/api_docs/python/model_card_toolkit/ModelCard) since it was one of few frameworks available for reference. + +Since that time, the AI/ML landscape has progressed at a rapid pace with both in terms of the design of model architectures and increased emphasis on providing model disclosure to conform with governmental regulations. *In order to account for these changes, the CycloneDX community plans to provide significant improvements and normative guidance in future versions of the specification.*
\newpage diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index 54f1374..520777a 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -2,11 +2,75 @@ ## Model parameters ->![Note] add diagram of model parameters +![](images/ml-anatomy-model-card-parameters.svg) -In general, model parameters describe values that are directly used to configure model processing applications and frameworks and their implementations of model architectures. For example, most models that appear in Hugging Face typically include configuration files for both the models and the tokenizers they are designed for use with the [Hugging Face Transformers](https://huggingface.co/docs/transformers/) library and its underlying use of the PyTorch framework. +This section will feature guidance on filling out information in the Cyclone model card's `modelParameters` object and its subcomponents including: -> [!NOTE] The CycloneDX ModelParameters were initially based upon [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) (now archived) which defines [ModelParameters](https://www.tensorflow.org/responsible_ai/model_card_toolkit/api_docs/python/model_card_toolkit/ModelParameters) that include key-value maps for both inputs and outputs alongside an array of their types; these maps will be accomplished using CycloneDX properties and the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy) reserved namespace `cdx:ai-ml:parameter` and `cdx:ai-ml:hyperparameter` as needed. +* [Model metadata](#model-metadata) + * [Approach](#approach) - The overall approach to learning used by the model for problem solving. + * [Task](#task) - Directly influences the input and/or output. Examples include classification, regression, clustering, etc. + * [Architecture](#architecture) - The model architecture family such as a Transformer network, convolutional neural network (CNN), residual neural network (RNN), LSTM neural network, etc. + +* [Declaring datasets](#declaring-datasets) + + +--- + +### Model metadata + +#### Approach + +##### Type + +Learning types describing the learning problem or hybrid learning problem. + +| Name | Description | +| !-- | !-- | +| "supervised" | Supervised machine learning involves training an algorithm on labeled data to predict or classify new data based on the patterns learned from the labeled examples. | +| "unsupervised" | Unsupervised machine learning involves training algorithms on unlabeled data to discover patterns, structures, or relationships without explicit guidance, allowing the model to identify inherent structures or clusters within the data. +| "reinforcement-learning" | Reinforcement learning is a type of machine learning where an agent learns to make decisions by interacting with an environment to maximize cumulative rewards, through trial and error. | +| "semi-supervised" | Semi-supervised machine learning utilizes a combination of labeled and unlabeled data during training to improve model performance, leveraging the benefits of both supervised and unsupervised learning techniques. | +| "self-supervised" | Self-supervised machine learning involves training models to predict parts of the input data from other parts of the same data, without requiring external labels, enabling learning from large amounts of unlabeled data. | + + +#### Task + +#### Architecture + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "metadata": + { + "component": + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + ... + "modelCard": { + "modelParameters": { + "task": "text-generation", + "architectureFamily": "transformer", + "modelArchitecture": "QWenLMHeadModel", + "approach": { + "type": "generative", + "motivations": ["text-generation", "conversational-ai"] + }, + ... + } + } + } +} +``` + +--- + +### Declaring Model configuration parameters & hyperparameters + +In general, model configuration parameters describe values that are directly used to configure model processing applications and frameworks and their implementations of model architectures. For example, most models that appear in Hugging Face typically include configuration files for both the models and the tokenizers they are designed for use with the [Hugging Face Transformers](https://huggingface.co/docs/transformers/) library and its underlying use of the PyTorch framework. + +> [!NOTE] The CycloneDX ModelParameters were initially based upon [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) (now archived) which defines [ModelParameters](https://www.tensorflow.org/responsible_ai/model_card_toolkit/api_docs/python/model_card_toolkit/ModelParameters) that include key-value maps for both inputs and outputs alongside an array of their types; these maps will be accomplished using CycloneDX properties and the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy) reserved namespace `cdx:ai-ml:model:parameter` and `cdx:ai-ml:model:hyperparameter` as needed. ###### Example: CycloneDX for the Qwen-7B model repository @@ -38,10 +102,10 @@ As shown in the [Qwen/Qwen-7B model repository files](0x20-Design-Model-Componen "type": "generative", "motivations": ["text-generation", "conversational-ai"] }, - "parameters": [ + "properties": [ { "name": "total_parameters", - "value": "7 billion", + "value": "7B", "description": "Total number of parameters in the model." }, { @@ -85,17 +149,69 @@ As shown in the [Qwen/Qwen-7B model repository files](0x20-Design-Model-Componen ###### Discussion of model card fields -- **parameters** - +- **properties** - >[!TODO] determine if we MUST also add "dependencies" to the composition to est. the relationship to the actual model repository. e.g., "dependencies": ["model-bom-ref"] -#### Model architecture + --- -### Quantitative Analysis +### Model inputs & outputs +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "metadata": + { + "component": + { + "type": "machine-learning-model", + ... + "modelCard": { + ... + "inputs": [ + {"format": "string"} + ], + "outputs": [ + {"format": "string"} + ] + } + } + } +} +``` + +### Quantitative analysis + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "metadata": + { + "component": + { + "type": "machine-learning-model", + ... + "modelCard": { + ... + "quantitativeAnalysis": { + "performanceMetrics": [ + { + "type": "benchmark_score", + "value": "specific benchmark score here", + "slice": "Specific benchmark name (e.g., MMLU, GSM8K)" + } + ] + } + } + } + } +} +``` --- @@ -178,10 +294,6 @@ Again, we continue to showcase the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Q } ``` - -### Model metadata - - --- ### Declaring datasets @@ -208,8 +320,6 @@ Specifically, the component `modelCard` object includes `modelParameters` which --- -### Model metadata -
\newpage
From 98c71b02ff5dc18550132cfb90caf5b41d286004 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 19 Jan 2026 15:38:53 -0600 Subject: [PATCH 025/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- .../en/0x22-Design-Model-Card-Parameters.md | 280 +++++++----------- ...Design-Model-Card-Quantitative-Analysis.md | 106 +++++++ 2 files changed, 218 insertions(+), 168 deletions(-) create mode 100644 ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index 520777a..d9df579 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -9,10 +9,12 @@ This section will feature guidance on filling out information in the Cyclone mod * [Model metadata](#model-metadata) * [Approach](#approach) - The overall approach to learning used by the model for problem solving. * [Task](#task) - Directly influences the input and/or output. Examples include classification, regression, clustering, etc. - * [Architecture](#architecture) - The model architecture family such as a Transformer network, convolutional neural network (CNN), residual neural network (RNN), LSTM neural network, etc. - -* [Declaring datasets](#declaring-datasets) - + * [Architecture](#architecture) - The model architecture family such as a Transformer network, Convolutional Neural Network (CNN), residual neural network (RNN), LSTM neural network, etc. +* [Datasets](#datasets) - The datasets used to train and evaluate the model. + * [Declaring datasets](#declaring-datasets) +* [Inputs & Outputs](#inputs--outputs) - +* [Declaring other properties](#declaring-other-properties) + * [Configuration parameters & hyperparameters](#configuration-parameters--hyperparameters) --- @@ -37,6 +39,9 @@ Learning types describing the learning problem or hybrid learning problem. #### Architecture + +###### Example: Model card metadata for the Qwen-7B model + ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", @@ -66,99 +71,39 @@ Learning types describing the learning problem or hybrid learning problem. --- -### Declaring Model configuration parameters & hyperparameters +### Datasets -In general, model configuration parameters describe values that are directly used to configure model processing applications and frameworks and their implementations of model architectures. For example, most models that appear in Hugging Face typically include configuration files for both the models and the tokenizers they are designed for use with the [Hugging Face Transformers](https://huggingface.co/docs/transformers/) library and its underlying use of the PyTorch framework. +Details the datasets used to train and evaluate the model. -> [!NOTE] The CycloneDX ModelParameters were initially based upon [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) (now archived) which defines [ModelParameters](https://www.tensorflow.org/responsible_ai/model_card_toolkit/api_docs/python/model_card_toolkit/ModelParameters) that include key-value maps for both inputs and outputs alongside an array of their types; these maps will be accomplished using CycloneDX properties and the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy) reserved namespace `cdx:ai-ml:model:parameter` and `cdx:ai-ml:model:hyperparameter` as needed. +#### Declaring datasets -###### Example: CycloneDX for the Qwen-7B model repository +Using CycloneDX there are two methods to provide information on the datasets used to train, test, and evaluate machine learning models. -The following example shows how the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model's parameters would be declared as a CycloneDX `modelCard`. +Specifically, the component `modelCard` object includes `modelParameters` which includes an array of `datasets` objects which can be of the following types: -As shown in the [Qwen/Qwen-7B model repository files](0x20-Design-Model-Component-Metadata.md#example-qwenqwen-7b-model-repository-files) example in the previous section, we see the model includes several configuration files including: +1. **In-line information**: provides in-line objects that provide for direct description of datasets and some of their typically cited attributes and characteristics. Typically, this method mirrors dataset information found in various model catalogs and provides a means for direct, simplified mapping to CycloneDX. + * *This method may be helpful if the datasets themselves are not public (i.e., directly referenceable), but informational details are.* +2. **Data component reference**: provides for the complete description of each dataset as its own CycloneDX component and referenced via its `bom-ref`. + * *This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information.* -- [config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/config.json) - which contains configuration parameters (as key-value pairs) used for initializing the model's implementation. -- [generation_config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/generation_config.json) - which contains model hyperparameters (as key-value pairs) and their suggested (default) values used for configuring the model for token generation (inference). +#### In-line information object model -```json -{ - "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... - "metadata": - { - "component": - { - "type": "machine-learning-model", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", - ..., - "modelCard": { - "modelParameters": { - "task": "text-generation", - "architectureFamily": "transformer", - "modelArchitecture": "QWenLMHeadModel", - "approach": { - "type": "generative", - "motivations": ["text-generation", "conversational-ai"] - }, - "properties": [ - { - "name": "total_parameters", - "value": "7B", - "description": "Total number of parameters in the model." - }, - { - "name": "context_length", - "value": "8192", - "description": "The maximum sequence length the model supports during pre-training and inference." - }, - { - "name": "vocab_size", - "value": "151936", - "description": "The size of the model's vocabulary." - }, - { - "name": "quantization_support", - "value": "4-bit, 8-bit", - "description": "Supported quantization levels for reduced memory usage, as seen in community variations like TheBloke/Qwen-7B-Chat-GPTQ." - } - ], - "inputs": [ - {"format": "string"} - ], - "outputs": [ - {"format": "string"} - ], - }, - "quantitativeAnalysis": { - "performanceMetrics": [ - { - "type": "benchmark_score", - "value": "specific benchmark score here", - "slice": "Specific benchmark name (e.g., MMLU, GSM8K)" - } - ] - }, - ... - } - } - } -} -``` +##### Example -###### Discussion of model card fields -- **properties** - +#### Data component references ->[!TODO] determine if we MUST also add "dependencies" to the composition to est. the relationship to the actual model repository. e.g., "dependencies": ["model-bom-ref"] +##### Example +--- +### Inputs & outputs ---- +Describes the input and output data types formats of the model. -### Model inputs & outputs +>[!Note] Please see the [](#mode) ```json { @@ -184,37 +129,10 @@ As shown in the [Qwen/Qwen-7B model repository files](0x20-Design-Model-Componen } ``` -### Quantitative analysis - -```json -{ - "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... - "metadata": - { - "component": - { - "type": "machine-learning-model", - ... - "modelCard": { - ... - "quantitativeAnalysis": { - "performanceMetrics": [ - { - "type": "benchmark_score", - "value": "specific benchmark score here", - "slice": "Specific benchmark name (e.g., MMLU, GSM8K)" - } - ] - } - } - } - } -} -``` --- +### Complete model card example ###### Example: CycloneDX Model Card for the Qwen-7B model @@ -230,93 +148,119 @@ Again, we continue to showcase the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Q "architectureFamily": "the architecture family goes here", "modelArchitecture": "The architecture of the model.", "datasets": [ - { - "type": "dataset", - "name": "Training Data", - "contents": { - "url": "https://example.com/path/to/dataset" - }, - "classification": "public" - } - ], - "inputs": [ - { - "format": "string" - } + { + "type": "dataset", + "name": "Training Data", + "contents": { + "url": "https://example.com/path/to/dataset" + }, + "classification": "public" + } ], - "outputs": [ - { - "format": "byte[]" - } - ] -}, -"quantitativeAnalysis": { - "performanceMetrics": [ - { - "type": "The type of performance metric", - "value": "The value of the performance metric", - "slice": "The name of the slice this metric was computed on. By default, assume this metric is not sliced", - "confidenceInterval": { - "lowerBound": "The lower bound of the confidence interval", - "upperBound": "The upper bound of the confidence interval" - } - } - ] -}, -"considerations": { + }, + + "considerations": { "users": [ - "Who are the intended users of the model?" + "Who are the intended users of the model?" ], "useCases": [ - "Who are the intended users of the model?" + "Who are the intended users of the model?" ], "technicalLimitations": [ - "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?" + "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?" ], "performanceTradeoffs": [ - "What are the known tradeoffs in accuracy/performance of the model?" + "What are the known tradeoffs in accuracy/performance of the model?" ], "ethicalConsiderations": [ - { - "name": "The name of the risk", - "mitigationStrategy": "Strategy used to address this risk" - } + { + "name": "The name of the risk", + "mitigationStrategy": "Strategy used to address this risk" + } ], "fairnessAssessments": [ - { - "groupAtRisk": "The groups or individuals at risk of being systematically disadvantaged by the model", - "benefits": "Expected benefits to the identified groups", - "harms": "Expected harms to the identified groups", - "mitigationStrategy": "With respect to the benefits and harms outlined, please describe any mitigation strategy implemented." - } + { + "groupAtRisk": "The groups or individuals at risk of being systematically disadvantaged by the model", + "benefits": "Expected benefits to the identified groups", + "harms": "Expected harms to the identified groups", + "mitigationStrategy": "With respect to the benefits and harms outlined, please describe any mitigation strategy implemented." + } ] } } ``` - --- -### Declaring datasets +### Declaring other properties -Using CycloneDX there are two methods to provide information on the datasets used to train, test, and evaluate machine learning models. +#### Configuration Parameters & hyperparameters -Specifically, the component `modelCard` object includes `modelParameters` which includes an array of `datasets` objects which can be of the following types: +In general, model configuration parameters describe values that are directly used to configure model processing applications and frameworks and their implementations of model architectures. For example, most models that appear in Hugging Face typically include configuration files for both the models and the tokenizers they are designed for use with the [Hugging Face Transformers](https://huggingface.co/docs/transformers/) library and its underlying use of the PyTorch framework. -1. **In-line information**: provides in-line objects that provide for direct description of datasets and some of their typically cited attributes and characteristics. Typically, this method mirrors dataset information found in various model catalogs and provides a means for direct, simplified mapping to CycloneDX. - * *This method may be helpful if the datasets themselves are not public (i.e., directly referenceable), but informational details are.* -2. **Data component reference**: provides for the complete description of each dataset as its own CycloneDX component and referenced via its `bom-ref`. - * *This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information.* +> [!NOTE] The CycloneDX ModelParameters were initially based upon [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) (now archived) which defines [ModelParameters](https://www.tensorflow.org/responsible_ai/model_card_toolkit/api_docs/python/model_card_toolkit/ModelParameters) that include key-value maps for both inputs and outputs alongside an array of their types; these maps will be accomplished using CycloneDX properties and the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy) reserved namespace `cdx:ai-ml:model:parameter` and `cdx:ai-ml:model:hyperparameter` as needed. -#### In-line information object model +###### Example: CycloneDX for the Qwen-7B model repository +The following example shows how the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model's parameters would be declared as a CycloneDX `modelCard`. -##### Example +As shown in the [Qwen/Qwen-7B model repository files](0x20-Design-Model-Component-Metadata.md#example-qwenqwen-7b-model-repository-files) example in the previous section, we see the model includes several configuration files including: +- [config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/config.json) - which contains configuration parameters (as key-value pairs) used for initializing the model's implementation. +- [generation_config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/generation_config.json) - which contains model hyperparameters (as key-value pairs) and their suggested (default) values used for configuring the model for token generation (inference). -#### Data component references +###### Example: Model parameters & hyperparameters for the Qwen-7B model -##### Example +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "metadata": + { + "component": + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + ..., + "modelCard": { + "modelParameters": { + ... + "properties": [ + { + "name": "cdx:ai-ml:model:parameter:total_parameters", + "value": "7B" + }, + { + "name": "cdx:ai-ml:model:parameter:context_length", + "value": "8192" + }, + { + "name": "cdx:ai-ml:model:parameter:vocab_size", + "value": "151936" + }, + { + "name": "cdx:ai-ml:model:parameter:quantization_support", + "value": "4-bit, 8-bit" + } + ] + }, + ... + } + } + } +} +``` + +###### Discussion of model card fields + +The values from the Qwen model's `model_config.json` were added to the CycloneDx model card's `properties` array using the CycloneDx reserved namespace for AI/ML. + +- **properties** + + * **total_parameters** - Total number of parameters in the model. + * **context_length** - The maximum sequence length the model supports during training and inference. + * **vocab_size** - The size of the model's vocabulary. + * **quantization_support** - Supported quantization levels for reduced memory usage, as seen in community variations like TheBloke/Qwen-7B-Chat-GPTQ. --- diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md new file mode 100644 index 0000000..3f9f3d1 --- /dev/null +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -0,0 +1,106 @@ +# ML-BOM Design and Best Practices + +## Quantitative analysis + +![](images/ml-anatomy-model-card-quant-analysis.svg) + +This section will feature guidance on filling out information in the Cyclone model card's `modelParameters` object and its subcomponents including: + +* [Quantitative analysis](#quantitative-analysis) +* [Graphics](#graphics) + +### Quantitative analysis + +A quantitative analysis of an AI model involves using mathematical and statistical methods to objectively measure and evaluate its performance, behavior, and outputs using numerical data, focusing on how much or how often, unlike qualitative analysis which looks at why. It assesses metrics like accuracy, precision, recall, efficiency, and consistency, transforming raw data into verifiable insights to understand patterns, test hypotheses, and ensure reliability for decision-making, moving beyond subjective human interpretation. + + +#### Key Aspects of Quantitative AI Analysis: + +* Numerical Metrics: Uses measurable data (e.g., error rates, latency, performance scores) rather than subjective feedback. +* Objective Evaluation: Provides reproducible, scalable results that can be compared across different models or versions. +* Pattern & Trend Detection: Identifies numerical patterns, correlations, and trends within large datasets that might be missed manually. +* Performance Benchmarking: Calculates specific scores (like F1-score, AUC, BLEU for LLMs) to compare models rigorously. +* Testing Hypotheses: Statistically tests assumptions about model behavior (e.g., "Does Model X consistently outperform Model Y on this task?"). +* Automation: AI itself can automate complex quantitative analysis, handling vast amounts of data and uncovering intricate relationships. + +--- + +#### Performance metrics + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "metadata": + { + "component": + { + "type": "machine-learning-model", + ... + "modelCard": { + ... + "quantitativeAnalysis": { + "performanceMetrics": [ + { + "type": "benchmark_score", + "value": "The value of the performance metric", + // "slice": "The name of the slice this metric was computed on. By default, assume this metric is not sliced", + "slice": "Specific benchmark name (e.g., MMLU, GSM8K)" + "confidenceInterval": { + "lowerBound": "The lower bound of the confidence interval", + "upperBound": "The upper bound of the confidence interval" + } + } + ] + } + } + } + } +} +``` + +#### Graphics + +TODO + +### Quantitative analysis + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "metadata": + { + "component": + { + "type": "machine-learning-model", + ... + "modelCard": { + ... + "quantitativeAnalysis": { + "graphics": [ + { + "description": "benchmark_score", + "collection": [ + { + "name": "string", + "image": { + "contentType": "", + "encoding": "base64", + "content": "string" + } + } + ] + + } + ] + } + } + } + } +} +``` + +
+\newpage +
From 7d4ede168d6ff5d6bf1b09b1064bdd668d756e9a Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 19 Jan 2026 16:59:00 -0600 Subject: [PATCH 026/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x22-Design-Model-Card-Parameters.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index d9df579..a860e64 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -12,7 +12,7 @@ This section will feature guidance on filling out information in the Cyclone mod * [Architecture](#architecture) - The model architecture family such as a Transformer network, Convolutional Neural Network (CNN), residual neural network (RNN), LSTM neural network, etc. * [Datasets](#datasets) - The datasets used to train and evaluate the model. * [Declaring datasets](#declaring-datasets) -* [Inputs & Outputs](#inputs--outputs) - +* [Inputs & Outputs](#inputs--outputs) - Describes the input and output data types (formats) of the model. * [Declaring other properties](#declaring-other-properties) * [Configuration parameters & hyperparameters](#configuration-parameters--hyperparameters) @@ -101,7 +101,7 @@ Specifically, the component `modelCard` object includes `modelParameters` which ### Inputs & outputs -Describes the input and output data types formats of the model. +Describes the input and output data types (formats) of the model. >[!Note] Please see the [](#mode) @@ -199,17 +199,14 @@ In general, model configuration parameters describe values that are directly use > [!NOTE] The CycloneDX ModelParameters were initially based upon [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) (now archived) which defines [ModelParameters](https://www.tensorflow.org/responsible_ai/model_card_toolkit/api_docs/python/model_card_toolkit/ModelParameters) that include key-value maps for both inputs and outputs alongside an array of their types; these maps will be accomplished using CycloneDX properties and the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy) reserved namespace `cdx:ai-ml:model:parameter` and `cdx:ai-ml:model:hyperparameter` as needed. -###### Example: CycloneDX for the Qwen-7B model repository - -The following example shows how the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model's parameters would be declared as a CycloneDX `modelCard`. +###### Example: Model parameters & hyperparameters for the Qwen-7B model As shown in the [Qwen/Qwen-7B model repository files](0x20-Design-Model-Component-Metadata.md#example-qwenqwen-7b-model-repository-files) example in the previous section, we see the model includes several configuration files including: - [config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/config.json) - which contains configuration parameters (as key-value pairs) used for initializing the model's implementation. - [generation_config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/generation_config.json) - which contains model hyperparameters (as key-value pairs) and their suggested (default) values used for configuring the model for token generation (inference). - -###### Example: Model parameters & hyperparameters for the Qwen-7B model +The JSON below shows how a few of the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model's parameters, as contained in the [config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/config.json) configuration file, would be declared within the CycloneDx `modelCard` object's `properties` array using the CycloneDx reserved namespace for AI/ML. ```json { @@ -241,7 +238,8 @@ As shown in the [Qwen/Qwen-7B model repository files](0x20-Design-Model-Componen { "name": "cdx:ai-ml:model:parameter:quantization_support", "value": "4-bit, 8-bit" - } + }, + ... ] }, ... @@ -251,9 +249,9 @@ As shown in the [Qwen/Qwen-7B model repository files](0x20-Design-Model-Componen } ``` -###### Discussion of model card fields +###### Discussion of model card properties -The values from the Qwen model's `model_config.json` were added to the CycloneDx model card's `properties` array using the CycloneDx reserved namespace for AI/ML. +The model card from above contains the following `cdx:ai-ml:model` properties: - **properties** From 42715491f19e3a2cf1c09e287caaa81dc47263bb Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 19 Jan 2026 17:30:37 -0600 Subject: [PATCH 027/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- .../en/0x22-Design-Model-Card-Parameters.md | 42 +++++++++++++++---- ...Design-Model-Card-Quantitative-Analysis.md | 23 +++++----- ML-BOM/en/0x40-Design-Other.md | 7 +--- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index a860e64..ea4a1a7 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -9,7 +9,8 @@ This section will feature guidance on filling out information in the Cyclone mod * [Model metadata](#model-metadata) * [Approach](#approach) - The overall approach to learning used by the model for problem solving. * [Task](#task) - Directly influences the input and/or output. Examples include classification, regression, clustering, etc. - * [Architecture](#architecture) - The model architecture family such as a Transformer network, Convolutional Neural Network (CNN), residual neural network (RNN), LSTM neural network, etc. + * [Architecture family](#architecture) - The model architecture family such as a Transformer network, Convolutional Neural Network (CNN), residual neural network (RNN), LSTM neural network, etc. + * [Architecture]() - The specific architecture of the model such as Transformer, GPT-1, ResNet-50, YOLOv3, etc. * [Datasets](#datasets) - The datasets used to train and evaluate the model. * [Declaring datasets](#declaring-datasets) * [Inputs & Outputs](#inputs--outputs) - Describes the input and output data types (formats) of the model. @@ -20,25 +21,48 @@ This section will feature guidance on filling out information in the Cyclone mod ### Model metadata +The `modelCard` fields, grouped in this section, are intended to describe so of the classifying metadata of the associated ML model. + #### Approach +The overall approach to learning used by the model for problem solving. + ##### Type -Learning types describing the learning problem or hybrid learning problem. +This field is intended to describe the specific **learning type* of the model. + +The following values are supported by CycloneDx for this field: -| Name | Description | -| !-- | !-- | -| "supervised" | Supervised machine learning involves training an algorithm on labeled data to predict or classify new data based on the patterns learned from the labeled examples. | -| "unsupervised" | Unsupervised machine learning involves training algorithms on unlabeled data to discover patterns, structures, or relationships without explicit guidance, allowing the model to identify inherent structures or clusters within the data. -| "reinforcement-learning" | Reinforcement learning is a type of machine learning where an agent learns to make decisions by interacting with an environment to maximize cumulative rewards, through trial and error. | -| "semi-supervised" | Semi-supervised machine learning utilizes a combination of labeled and unlabeled data during training to improve model performance, leveraging the benefits of both supervised and unsupervised learning techniques. | -| "self-supervised" | Self-supervised machine learning involves training models to predict parts of the input data from other parts of the same data, without requiring external labels, enabling learning from large amounts of unlabeled data. | +| Value | Description | +|---|---| +| **supervised** | Supervised machine learning involves training an algorithm on labeled data to predict or classify new data based on the patterns learned from the labeled examples. | +| **unsupervised** | Unsupervised machine learning involves training algorithms on unlabeled data to discover patterns, structures, or relationships without explicit guidance, allowing the model to identify inherent structures or clusters within the data. +| **reinforcement-learning** | Reinforcement learning is a type of machine learning where an agent learns to make decisions by interacting with an environment to maximize cumulative rewards, through trial and error. | +| **semi-supervised** | Semi-supervised machine learning utilizes a combination of labeled and unlabeled data during training to improve model performance, leveraging the benefits of both supervised and unsupervised learning techniques. | +| **self-supervised** | Self-supervised machine learning involves training models to predict parts of the input data from other parts of the same data, without requiring external labels, enabling learning from large amounts of unlabeled data. | #### Task +Describes the primary task of (or goal) of the machine learning model. Some examples include: + +* **Anomaly Detection** - Identifying outliers or unusual patterns in data. +* **Classification** - Categorizing inputs into predefined labels (e.g., spam/not-spam, image recognition). +* **Clustering** - Grouping unlabeled data based on similar characteristics (e.g., customer segmentation). +* **Dimensionality Reduction** - Simplifying complex data by reducing the number of variables while preserving core information. +* **Generation** - Creating new data based upon prompted instructions (e.g., Large Language Models (LLMs), image or audio diffusion models, etc.). +* **Recommendation/Association** - Finding relationships between items (e.g., "users who bought this also bought..."). +* **Regression** - Predicting continuous numerical values (e.g., house prices, temperature forecasting). + + +#### Architecture family + +TODO + + #### Architecture +TODO ###### Example: Model card metadata for the Qwen-7B model diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 3f9f3d1..a50b31f 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -4,24 +4,27 @@ ![](images/ml-anatomy-model-card-quant-analysis.svg) -This section will feature guidance on filling out information in the Cyclone model card's `modelParameters` object and its subcomponents including: +This section will feature guidance on filling out information in the Cyclone model card's `quantitativeAnalysis` object and its subcomponents including: -* [Quantitative analysis](#quantitative-analysis) +* [Performance metrics](#performance-metrics) * [Graphics](#graphics) -### Quantitative analysis +--- -A quantitative analysis of an AI model involves using mathematical and statistical methods to objectively measure and evaluate its performance, behavior, and outputs using numerical data, focusing on how much or how often, unlike qualitative analysis which looks at why. It assesses metrics like accuracy, precision, recall, efficiency, and consistency, transforming raw data into verifiable insights to understand patterns, test hypotheses, and ensure reliability for decision-making, moving beyond subjective human interpretation. +# What is quantitative analysis +A quantitative analysis of an AI model involves using mathematical and statistical methods to objectively measure and evaluate its performance, behavior, and outputs using numerical data, focusing on how much or how often, unlike qualitative analysis which looks at why. It assesses metrics like accuracy, precision, recall, efficiency, and consistency, transforming raw data into verifiable insights to understand patterns, test hypotheses, and ensure reliability for decision-making, moving beyond subjective human interpretation. #### Key Aspects of Quantitative AI Analysis: -* Numerical Metrics: Uses measurable data (e.g., error rates, latency, performance scores) rather than subjective feedback. -* Objective Evaluation: Provides reproducible, scalable results that can be compared across different models or versions. -* Pattern & Trend Detection: Identifies numerical patterns, correlations, and trends within large datasets that might be missed manually. -* Performance Benchmarking: Calculates specific scores (like F1-score, AUC, BLEU for LLMs) to compare models rigorously. -* Testing Hypotheses: Statistically tests assumptions about model behavior (e.g., "Does Model X consistently outperform Model Y on this task?"). -* Automation: AI itself can automate complex quantitative analysis, handling vast amounts of data and uncovering intricate relationships. +* **Numerical Metrics**: Uses measurable data (e.g., error rates, latency, performance scores) rather than subjective feedback. +* **Performance Benchmarking**: Calculates specific scores (like F1-score, AUC, BLEU for LLMs) to compare models rigorously. +* **Objective Evaluation**: Provides reproducible, scalable results that can be compared across different models or versions. +* **Pattern & Trend Detection**: Identifies numerical patterns, correlations, and trends within large datasets that might be missed manually. +* **Testing Hypotheses**: Statistically tests assumptions about model behavior (e.g., "Does Model X consistently outperform Model Y on this task?"). +* **Automation**: AI itself can automate complex quantitative analysis, handling vast amounts of data and uncovering intricate relationships. + + --- diff --git a/ML-BOM/en/0x40-Design-Other.md b/ML-BOM/en/0x40-Design-Other.md index 11da965..c0c1ed8 100644 --- a/ML-BOM/en/0x40-Design-Other.md +++ b/ML-BOM/en/0x40-Design-Other.md @@ -2,19 +2,14 @@ ## Other -This section describes the design and best practices when providing information for a CycloneDX `modelCard` in an ML-BOM as part of the model's CycloneDX `component` definition. +This section describes the design and best practices when providing other model-related information an ML model's component and model card within a CycloneDX ML-BOM. For convenience, here are links to the specific sections for each of those informational areas: -- [Model metadata](#model-metadata) -- [Model architecture]() -- [Datasets]() - [Tokenizers and prompt templates]() - [Hardware, software & frameworks]() - [Training & testing details]() - [Intended use & ethics]() -- [Environmental impacts]() -
\newpage From 71a4290bf93b41f90283bb234e8ca2fd40845fca Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 21 Jan 2026 15:08:40 -0600 Subject: [PATCH 028/111] Provide object design informaton for the ML-BOM Signed-off-by: Matt Rutkowski --- .../en/0x22-Design-Model-Card-Parameters.md | 57 ++++++++++++++----- .../0x24-Design-Model-Card-Considerations.md | 46 +++++++++++++++ 2 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 ML-BOM/en/0x24-Design-Model-Card-Considerations.md diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index ea4a1a7..9ca3dd5 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -9,8 +9,9 @@ This section will feature guidance on filling out information in the Cyclone mod * [Model metadata](#model-metadata) * [Approach](#approach) - The overall approach to learning used by the model for problem solving. * [Task](#task) - Directly influences the input and/or output. Examples include classification, regression, clustering, etc. - * [Architecture family](#architecture) - The model architecture family such as a Transformer network, Convolutional Neural Network (CNN), residual neural network (RNN), LSTM neural network, etc. - * [Architecture]() - The specific architecture of the model such as Transformer, GPT-1, ResNet-50, YOLOv3, etc. + * [Architecture family](#architecture-family) - The model architecture family such as a Transformer network, Convolutional Neural Network (CNN), residual neural network (RNN), LSTM neural network, etc. + * [Model architecture](#model-architecture) - The specific architecture of the model such as Transformer, GPT-1, ResNet-50, YOLOv3, etc. + * [External references](#external-references) * [Datasets](#datasets) - The datasets used to train and evaluate the model. * [Declaring datasets](#declaring-datasets) * [Inputs & Outputs](#inputs--outputs) - Describes the input and output data types (formats) of the model. @@ -25,15 +26,9 @@ The `modelCard` fields, grouped in this section, are intended to describe so of #### Approach -The overall approach to learning used by the model for problem solving. +Describes the general learning approach used to train the model. Currently, the approach is simply described by a single `type` field which has the following supported values: -##### Type - -This field is intended to describe the specific **learning type* of the model. - -The following values are supported by CycloneDx for this field: - -| Value | Description | +| Type | Description | |---|---| | **supervised** | Supervised machine learning involves training an algorithm on labeled data to predict or classify new data based on the patterns learned from the labeled examples. | | **unsupervised** | Unsupervised machine learning involves training algorithms on unlabeled data to discover patterns, structures, or relationships without explicit guidance, allowing the model to identify inherent structures or clusters within the data. @@ -41,6 +36,7 @@ The following values are supported by CycloneDx for this field: | **semi-supervised** | Semi-supervised machine learning utilizes a combination of labeled and unlabeled data during training to improve model performance, leveraging the benefits of both supervised and unsupervised learning techniques. | | **self-supervised** | Self-supervised machine learning involves training models to predict parts of the input data from other parts of the same data, without requiring external labels, enabling learning from large amounts of unlabeled data. | +Please note that links to external documentation that detail the model training approach (and other detailed information) can be provided using [external references](#external-references) which is discussed later in this section. #### Task @@ -54,13 +50,11 @@ Describes the primary task of (or goal) of the machine learning model. Some exa * **Recommendation/Association** - Finding relationships between items (e.g., "users who bought this also bought..."). * **Regression** - Predicting continuous numerical values (e.g., house prices, temperature forecasting). - #### Architecture family TODO - -#### Architecture +#### Model architecture TODO @@ -83,8 +77,7 @@ TODO "architectureFamily": "transformer", "modelArchitecture": "QWenLMHeadModel", "approach": { - "type": "generative", - "motivations": ["text-generation", "conversational-ai"] + "type": "supervised" }, ... } @@ -93,6 +86,40 @@ TODO } ``` + +#### External references + +Most models are fully described in terms of research papers, articles and other reference documents. In those cases, they should be provided as `externalReferences` under the `component`. + +###### Example: "Qwen Technical Report" + +This shows how the Qwen research team disclosed comprehensive details about the Qwen model's design, training, implementation and evaluation as a formal research paper in the the Cornell University's arXiv scholarly article distribution service. + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "metadata": + { + "component": + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + ..., + "externalReferences": [ + { + "type": "documentation", + "url": "https://arxiv.org/abs/2309.16609", + "comment": "Qwen Technical Report" + } + ], + ... + } + } +} + +``` + --- ### Datasets diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md new file mode 100644 index 0000000..3e2d594 --- /dev/null +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -0,0 +1,46 @@ +# ML-BOM Design and Best Practices + +## Considerations + +![](images/ml-anatomy-model-card-considerations.svg) + +This section will feature guidance on filling out information in the Cyclone model card's `considerations` object and its subcomponents including: + +This section will feature guidance on filling out information in the Cyclone model card's `modelParameters` object and its subcomponents including: + +* [Users](#users) +* [Use cases](#use-cases) +* [Technical limitations](#technical-limitations) +* [Performance Tradeoffs](#performance-tradeoffs) +* [Fairness assessments](#fairness-assessments) +* [Environmental considerations](#environmental-considerations) + +--- + +### Users + +--- + +### Use cases + +--- + +### Technical limitations + +--- + +### Performance Tradeoffs + +--- + +### Fairness assessments + +--- + +### Environmental considerations + +--- + +
+\newpage +
From 062f4a60341862978ff1876bbfc7901feb01047b Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 22 Jan 2026 09:20:52 -0600 Subject: [PATCH 029/111] Author the Model Card Parameters sections Signed-off-by: Matt Rutkowski --- .../en/0x22-Design-Model-Card-Parameters.md | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index 9ca3dd5..81590b8 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -132,12 +132,23 @@ Using CycloneDX there are two methods to provide information on the datasets use Specifically, the component `modelCard` object includes `modelParameters` which includes an array of `datasets` objects which can be of the following types: -1. **In-line information**: provides in-line objects that provide for direct description of datasets and some of their typically cited attributes and characteristics. Typically, this method mirrors dataset information found in various model catalogs and provides a means for direct, simplified mapping to CycloneDX. - * *This method may be helpful if the datasets themselves are not public (i.e., directly referenceable), but informational details are.* -2. **Data component reference**: provides for the complete description of each dataset as its own CycloneDX component and referenced via its `bom-ref`. - * *This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information.* +1. **In-line information**: provides in-line objects that provide for direct description of datasets and some of their typically cited attributes and characteristics. +2. **Data component references**: provides for the complete description of each dataset as its own CycloneDX component and referenced via its `bom-ref`. + +The next sections will discuss the considerations for each and example how to use both of these methods. + +#### In-line information + +This method simplifies the association between training datasets and model cards, specifically addressing scenarios where data is difficult to reference as an independent component. + +Key applications: + +* Filtered Data: Documenting specific slices of data used for fine-tuning. +* Private Repositories: Providing transparency via BOMs for non-public datasets. +* Unstructured Sources: Referencing data not housed in traditional databases or management tools. + + -#### In-line information object model ##### Example @@ -145,6 +156,8 @@ Specifically, the component `modelCard` object includes `modelParameters` which #### Data component references +* *This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information.* + ##### Example From 40df6f18af8107a1f3f269b3e22e63341c70b71c Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 22 Jan 2026 11:15:57 -0600 Subject: [PATCH 030/111] Author the Model Card Parameters sections Signed-off-by: Matt Rutkowski --- .../0x20-Design-Model-Component-Metadata.md | 26 ++++++---- .../en/0x22-Design-Model-Card-Parameters.md | 50 ++++++++++++++++--- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 226a160..f225bd8 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -52,7 +52,9 @@ The object model's pseudo-schema would look something like this: "component": { "type": "machine-learning-model", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", + "purl": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "version": "ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", ... } ... @@ -61,6 +63,10 @@ The object model's pseudo-schema would look something like this: } ``` +###### Discussion of fields + +* **bom-ref** - Please note the `bom-ref` value includes the first seven characters of the larger hash value from the `purl` component identifier which is sufficient for local identification within the BOM itself. + #### Model repositories as components When referencing an ML model as a component, it typically means you are referencing a **model repository** comprised of metadata and a set of files (e.g., pre-trained tensor data in various formats, model configurations, tokenizers, tokenizer configurations, prompt templates, Python code, etc.) which would be selectively used with various, compatible AI or ML applications and frameworks. @@ -82,7 +88,7 @@ Since the the model repository is hosted in Hugging Face Hub, the [Huggingface p "component": { "type": "machine-learning-model", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", "purl": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", "group": "Qwen" "manufacturer": "Alibaba Cloud", @@ -154,7 +160,7 @@ The following example shows how a registered names for a fictional company ACME "component": { "properties": [ { - "name": 'acme:research:model:llm:id', + "name": "acme:research:model:llm:id", "value": "MODEL-ID-12345-INTERNAL" }, ... @@ -199,14 +205,14 @@ Note that we use the Package URL syntax to provide the additional path (with the "component": { "type": "machine-learning-model", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", ... "components": [ { "type": "file", "name": "config.json", "description": "Model configuration file using the 'QWenLMHeadModel' model class in Hugging Face Transformers", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@e7a368b#config.json", "purl": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", ... }, @@ -214,7 +220,7 @@ Note that we use the Package URL syntax to provide the additional path (with the "type": "file", "name": "configuration_qwen.py", "description": "Python 'QWenConfig' class implementation for the Qwen-7B model using Hugging Face Transformers", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@a6ca629#configuration_qwen.py", "purl": "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", ... }, @@ -222,7 +228,7 @@ Note that we use the Package URL syntax to provide the additional path (with the "type": "data", "name": "model-00001-of-00008.safetensors", "description": "Model tensor data (01 of 08)", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6#model-00001-of-00008.safetensors", "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", "data": { "type": "dataset", @@ -234,7 +240,7 @@ Note that we use the Package URL syntax to provide the additional path (with the "type": "data", "name": "model-00002-of-00008.safetensors", "description": "Model tensor data (02 of 08)", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@abcb6#model-00002-of-00008.safetensors", "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", "data": { "type": "dataset", @@ -255,12 +261,12 @@ then the model component's new hierarchy of composing files would be described a ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... + ..., "composition": [ { "aggregate": "complete", "assemblies": [ - "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", ] } ], diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index 81590b8..eca8070 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -69,7 +69,7 @@ TODO "component": { "type": "machine-learning-model", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", ... "modelCard": { "modelParameters": { @@ -104,7 +104,7 @@ This shows how the Qwen research team disclosed comprehensive details about the "component": { "type": "machine-learning-model", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", ..., "externalReferences": [ { @@ -143,11 +143,46 @@ This method simplifies the association between training datasets and model cards Key applications: -* Filtered Data: Documenting specific slices of data used for fine-tuning. -* Private Repositories: Providing transparency via BOMs for non-public datasets. -* Unstructured Sources: Referencing data not housed in traditional databases or management tools. +* **Filtered Data**: Documenting specific slices or individual snippets of data used for fine-tuning or testing. +* **Private Repositories**: Providing transparency via BOMs for non-public datasets in public model cards (e.g, private data used for models in the healthcare or financial services industries). +* **Unstructured Sources**: Referencing data not housed in traditional databases or management tools (e.g., data within S3 buckets, event data within Security information and event management (SIEM) systems). +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.7", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "component": + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/m42-health/Llama3-Med42-8B@ceab7e7", + "purl": "pkg:huggingface/m42-health/Llama3-Med42-8B@ceab7e7ee4b9dbde7ba82867f34274db51487d83", + "description": "Med42-v2 introduces a suite of clinical large language models (LLMs) designed to address the limitations of generic models in healthcare settings. These models are built on Llama3 architecture and fine-tuned using specialized clinical data." + ..., + "modelCard": { + "modelParameters": { + ..., + "datasets": [ + { + "type": "dataset", + "name": "Training Data", + "contents": { + "url": "https://example.com/path/to/dataset" + }, + "classification": "public" + } + ], + ... + } + } + } + } +} +``` @@ -156,7 +191,8 @@ Key applications: #### Data component references -* *This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information.* +This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information as a full, CycloneDX component. + ##### Example @@ -281,7 +317,7 @@ The JSON below shows how a few of the [Qwen/Qwen-7B](https://huggingface.co/Qwen "component": { "type": "machine-learning-model", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", ..., "modelCard": { "modelParameters": { From 4cb27bd891542b7e8ef7a4e5ac981ccf2910edf0 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 22 Jan 2026 11:34:04 -0600 Subject: [PATCH 031/111] Author the Model Card Parameters sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x90-Appendix-A_Glossary.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/ML-BOM/en/0x90-Appendix-A_Glossary.md b/ML-BOM/en/0x90-Appendix-A_Glossary.md index 041d62c..c0106cd 100644 --- a/ML-BOM/en/0x90-Appendix-A_Glossary.md +++ b/ML-BOM/en/0x90-Appendix-A_Glossary.md @@ -1,5 +1,23 @@ # Appendix A: Glossary +##### Activation function + +An activation function is a mathematical operation applied to a neuron's output to introduce non-linearity, allowing the model to learn complex patterns beyond simple straight lines, essentially deciding if and how much a neuron "fires" based on its weighted inputs. [1] + +[1] [Activation functions in neural networks](https://www.youtube.com/watch?v=v1MhJs4A1i4&t=89s) + +##### Quantization + +A technique to reduce the computational and memory costs of running inference by representing the ([tensor](#tensor)) weights and [activations](#activation-function) with low-precision data types like 8-bit integer (int8) instead of the usual 32-bit floating point (float32). [1] + +[1] [Hugging Face - Quantization](https://huggingface.co/docs/optimum/en/concept_guides/quantization#quantization) + +##### Neural network + +A neural network consists of connected units or nodes called artificial neurons, which loosely model the neurons in the brain. Each artificial neuron receives signals from connected neurons, then processes them and sends a signal to other connected neurons. The "signal" is a real number, and the output of each neuron is computed by some non-linear function of the totality of its inputs, called the [activation function](#activation-function). [1] + +[1] [Wikipedia - Neural network (machine_learning)](https://en.wikipedia.org/wiki/Neural_network_(machine_learning)) + ##### Tensor In machine learning, the term tensor typically refers to data organized in a multidimensional array (M-way array), informally referred to as a "data tensor". Relational observations and concepts, established via ML model training of text, images, movies, sounds, and more can be stored in these "data tensors", and further analyzed either by artificial neural networks or tensor methods. [1] From 51f13d52463f6e76c674e295bdefd0e093bdcf54 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 22 Jan 2026 11:58:27 -0600 Subject: [PATCH 032/111] Author the Model Card Parameters sections Signed-off-by: Matt Rutkowski --- .../0x20-Design-Model-Component-Metadata.md | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index f225bd8..8258d28 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -171,8 +171,48 @@ The following example shows how a registered names for a fictional company ACME ##### Identifying a specific model quantization -> [!TODO] -> Need to discuss with PURL community as this is not exampled for Huggingface package type. +Some model repositories may contain different [quantizations](0x90-Appendix-A_Glossary.md#quantization) to select from in order to optimize when running on different target inference runtimes and hardware footprints. + +In general, these are referenceable as (often single) files within a model repository each of which can be described as a CycloneDX component as shown in the next section [Describing a model repository as a CycloneDX assembly](#describing-a-model-repository-as-a-cyclonedx-assembly). + +###### Example: Qwen/Qwen3-8B-GGUF + +This example uses the model repository [Qwen/Qwen3-8B-GGUF](https://huggingface.co/Qwen/Qwen3-8B-GGUF) which contains several quantizations of the Qwen3-8B model (published originally in a non-quantized format elsewhere) in [GGUF format](0x90-Appendix-A_Glossary.md#gguf-gpt-generated-unified-format). + +These quantized GGUF models are each individual files in the repository: + +* Qwen3-8B-Q4_K_M.gguf +* Qwen3-8B-Q5_0.gguf +* Qwen3-8B-Q6_K.gguf +* Qwen3-8B-Q8_0.gguf + +Each can be specifically identified in a CycloneDX component using a Package URL (PURL). For example, the `Qwen3-8B-Q4_K_M.gguf` model would be declared as follows: + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.7", + "serialNumber": "urn:uuid:1ad676cb-6b40-4068-ae91-ebd1533dbf58", + "version": 1, + ..., + "components": [ + { + "name": "Qwen3-8B-Q4_K_M.gguf", + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen3-8B-GGUF@7c41481#Qwen3-8B-Q4_K_M.gguf", + "purl": "pkg:huggingface/Qwen/Qwen3-8B-GGUF@7c41481f57cb95916b40956ab2f0b139b296d974#Qwen3-8B-Q4_K_M.gguf", + "version": "7c41481f57cb95916b40956ab2f0b139b296d974", + ... + } + ], + ... +} +``` + +###### Field notes + +* **type** - the type has the value `machine-learning-model` since the single file contains all the information (e.g., default configuration parameters, references to architectures and tokenizers, prompt template, etc.) needed to run the model in GGUF inference frameworks. --- From 208742cbe44336830370d99d6fd9756e026fbcfe Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 22 Jan 2026 14:03:09 -0600 Subject: [PATCH 033/111] Author the Model Card Parameters sections Signed-off-by: Matt Rutkowski --- .../en/0x22-Design-Model-Card-Parameters.md | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index eca8070..3264b27 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -52,7 +52,22 @@ Describes the primary task of (or goal) of the machine learning model. Some exa #### Architecture family -TODO +The model architecture family th + +such as a Transformer network, Convolutional Neural Network (CNN), residual neural network (RNN), LSTM neural network, etc. + +An architecture family defines the structural and data processing methodology of the model's neural network. It does not typically describe a single model, but rather describes the general design of the neural network (NN), mathematical approach, context and attention mechanisms and the like. It should provide insight to those versed in the field as how the model general is constructed. + +Some examples of commonly referenced neural network (NN) architecture families include: + +* **Transformers** - an architecture designed to process sequential data (like text, speech, or images) in parallel rather than in order. +* **Convolutional Neural Network (CNN)** - an architecture designed to process efficiently detect patterns (like edges, shapes, and textures) to typically classify or analyze visual (videos/image) or auditory data, but can applied to text analysis, behavioral patterns and more. +* **Recurrent Neural Network (RNN)** - an architecture designed for processing sequential data like text, speech, and time series, typically used for tasks where order matters, such as language translation, speech recognition and time-series forecasting. +* **Long Short-Term Memory (LSTM)** - a specialized variant of a Recurrent Neural Network (RNN) architecture designed specifically to overcome the limitations of traditional RNNs in learning long-term dependencies. +* **Gated Recurrent Units (GRUs)** a specialized variant of a Recurrent Neural Network (RNN) architecture designed to overcome challenges like the vanishing gradient problem and enhance the modeling of long-term dependencies in sequential datasets. +* **Generative Adversarial Networks (GANs)** - an architecture used to train two neural networks, a *Generator* and a *Discriminator*, to compete against each other to generate more authentic data from a starting training dataset. The Generator tries to fool the Discriminator by creating fake data, while the Discriminator tries to identify fakes, leading to continuous improvement in data quality. + +Again, the list above represents architecture families that are commonly referenced in research to establish an understanding of general model design; however, the architectural landscape continues to grow as researchers specialize and optimize for different use cases, goals and datasets. #### Model architecture @@ -63,14 +78,14 @@ TODO ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... + ..., "metadata": { "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ... + ..., "modelCard": { "modelParameters": { "task": "text-generation", From 293205c69d13994c48dfa89106554400d8b323a5 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 22 Jan 2026 14:41:24 -0600 Subject: [PATCH 034/111] Author the Model Card Parameters sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x22-Design-Model-Card-Parameters.md | 15 +++++++++++++++ ML-BOM/en/0x91-Appendix-B_References.md | 2 ++ 2 files changed, 17 insertions(+) diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index 3264b27..4debcdd 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -73,8 +73,20 @@ Again, the list above represents architecture families that are commonly referen TODO +The model architecture field is intended to include a specific keywords to identify an implementation (class or library) or technical descriptors of the architectural "blueprint" needed to run a specific model. + +These are typically found in one of several locations relative to the model: + +* **Model Card** - the associated "model card" (e.g., `README.md` in Hugging Face) may contain a mentions of specific class names like `LlamaForCausalLM`, `BertModel`, or `VisionTransformer`. +* **Framework-Specific Implementation Keywords** or tags - +Depending on your code environment (PyTorch, TensorFlow, llama.cpp, etc.) that identify specific model code within the platform or environment. +* **Framework-Specific Configuration files** (e.g., Hugging Face transformer's `config.json` file) - may contain the name of the class or function used to configure the framework for the specific implementation recommended for the associated model. +* **Academic Research Papers** (e.g., arXiv) - may include detailed descriptors of processing algorithms, supported training or inference engines or specific, named implementations + ###### Example: Model card metadata for the Qwen-7B model +This example shows best practice for the Qwen-7B model using information published within and for the model's repository in Hugging Face. + ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", @@ -101,6 +113,9 @@ TODO } ``` +###### Field discussion + +* **modelArchitecture** - the value `QWenLMHeadModel` was located in the model's `config.json` model configuration file. #### External references diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index 2af395d..0efb7fd 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -42,10 +42,12 @@ The following AI or ML technologies were referenced in discussion and/or example * [Hugging Face](https://huggingface.co/) - an open-source platform and community for Artificial Intelligence (AI) and Machine Learning (ML). * [Hugging Face Transformers](https://huggingface.co/docs/transformers/) - a library that simplifies the training and inference of models that have a transformer architecture which uses PyTorch types and implementations "under-the-covers". +* [llama.cpp](https://github.com/ggml-org/llama.cpp) - an open-source inference engine, written in C++, designed for high-performance Large Language Model (LLM) execution across diverse hardware. * [PyTorch](https://pytorch.org/) - an optimized tensor library and framework used for deep learning on GPUs and CPUs. * [TensorFlow](https://www.tensorflow.org/) - An end-to-end open source machine learning platform. * [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) (archived) - streamlines and automates generation of Model Cards, machine learning documents that provide context and transparency into a model's development and performance. + --- #### Model references From dca83ed58510ef66aecf9f4b7faae65d619a8aae Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 22 Jan 2026 17:47:06 -0600 Subject: [PATCH 035/111] Author the Model Card Parameters sections Signed-off-by: Matt Rutkowski --- .../en/0x22-Design-Model-Card-Parameters.md | 91 ++++++++++++++++--- 1 file changed, 78 insertions(+), 13 deletions(-) diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index 4debcdd..b2b2c57 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -178,6 +178,10 @@ Key applications: * **Unstructured Sources**: Referencing data not housed in traditional databases or management tools (e.g., data within S3 buckets, event data within Security information and event management (SIEM) systems). +##### Example: Custom health model with private dataset + +This example shows a model fine-tuned (by a fictional "ACME Health" company) from the public [m42-health/Llama3-Med42-8B](https://huggingface.co/m42-health/Llama3-Med42-8B) model using a private dataset. + ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", @@ -189,9 +193,9 @@ Key applications: "component": { "type": "machine-learning-model", - "bom-ref": "pkg:huggingface/m42-health/Llama3-Med42-8B@ceab7e7", - "purl": "pkg:huggingface/m42-health/Llama3-Med42-8B@ceab7e7ee4b9dbde7ba82867f34274db51487d83", - "description": "Med42-v2 introduces a suite of clinical large language models (LLMs) designed to address the limitations of generic models in healthcare settings. These models are built on Llama3 architecture and fine-tuned using specialized clinical data." + "bom-ref": "pkg:huggingface/acme-health/custom-Llama3-Med42-8B@2ee9dc9", + "purl": "pkg:huggingface/acme-health/custom-Llama3-Med42-8B@2ee9dc99-cc50-4490-9d6e-9ebf6e39f82f", + "description": "Customized Med42-v2 large language models (LLMs) which uses the Llama3 architecture and fine-tuned using private clinical dataset." ..., "modelCard": { "modelParameters": { @@ -199,11 +203,21 @@ Key applications: "datasets": [ { "type": "dataset", - "name": "Training Data", + "name": "UltraFeed- +back dataset", + "classification": "public", + "contents": { + "url": "https://huggingface.co/datasets/openbmb/UltraFeedback" + } + }, + ..., + { + "type": "dataset", + "name": "ACME Midwest health data", + "classification": "private", "contents": { - "url": "https://example.com/path/to/dataset" - }, - "classification": "public" + "url": "https://acme.ai/adatasets/health/patient?region=midwest" + } } ], ... @@ -214,18 +228,69 @@ Key applications: } ``` - - -##### Example - - #### Data component references This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information as a full, CycloneDX component. +##### Example: health model with private dataset + +This example shows the recommended best practice of declaring the datasets for the base model used in the previous "in-line" example (i.e., [m42-health/Llama3-Med42-8B](https://huggingface.co/m42-health/Llama3-Med42-8B)) as their own CycloneDX components. + +The public datasets, as documented in the model's research paper include: +* [openbmb/UltraFeedback](https://huggingface.co/datasets/openbmb/UltraFeedback) +* [snorkelai/Snorkel-Mistral-PairRM-DPO](https://huggingface.co/snorkelai/Snorkel-Mistral-PairRM-DPO) -##### Example +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.7", + "serialNumber": "urn:uuid:eb033070-85d1-45f4-9eb7-f50510f83853", + "version": 1, + "metadata": { + "component": + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/acme-health/custom-Llama3-Med42-8B@ceab7e7", + "purl": "pkg:huggingface/acme-health/Llama3-Med42-8B@ceab7e7ee4b9dbde7ba82867f34274db51487d83", + "description": "an open, clinical large language models (LLM) instruct and preference-tuned by M42 to expand access to medical knowledge. Built off LLaMA-3 and designed to provide high-quality answers to medical questions." + ..., + "modelCard": { + "modelParameters": { + ..., + "datasets": [ + { + "ref": "pkg:huggingface/openbmb/UltraFeedback@40b4365" + }, + { + "ref": "pkg:huggingface/snorkelai/Snorkel-Mistral-PairRM-DPO@07af5d0a" + } + ], + ... + } + } + } + }, + ..., + "components": [ + { + "name": "UltraFeed-back dataset", + "type": "data", + "bom-ref": "pkg:huggingface/openbmb/UltraFeedback@40b4365", + "purl": "pkg:huggingface/openbmb/UltraFeedback@40b436560ca83a8dba36114c22ab3c66e43f6d5e", + ... + }, + { + "name": "UltraFeed-back dataset", + "type": "data", + "bom-ref": "pkg:huggingface/snorkelai/Snorkel-Mistral-PairRM-DPO@07af5d0a", + "purl": "pkg:huggingface/snorkelai/Snorkel-Mistral-PairRM-DPO@07af5d0a875b4c692dfaff6c675b10af07b45511", + ... + } + ] +} +``` --- From 7c6a8df6008012bc50229d8ada1789a9af1ca49f Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 22 Jan 2026 18:00:48 -0600 Subject: [PATCH 036/111] Author the Model Card Parameters sections Signed-off-by: Matt Rutkowski --- .../en/0x22-Design-Model-Card-Parameters.md | 69 ++----------------- 1 file changed, 6 insertions(+), 63 deletions(-) diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index b2b2c57..6e317ad 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -298,7 +298,9 @@ The public datasets, as documented in the model's research paper include: Describes the input and output data types (formats) of the model. ->[!Note] Please see the [](#mode) +>[!Note] The current object used to describe model inputs and outputs is limited to describing the data types strictly used for training and inference. Future revisions of CycloneDx plan to expand these objects to provide more detailed information especially in regard to names, formats and defaults for model configuration parameters and hyperparameters. + +In order to provide information on model parameters and hyperparameters using existing CycloneDx schema, it is recommended best practice as shown in the next section "[Declaring other properties](#declaring-other-properties)" and its "[Example: Model parameters & hyperparameters for the Qwen-7B model](#example-model-parameters--hyperparameters-for-the-qwen-7b-model)". ```json { @@ -309,9 +311,10 @@ Describes the input and output data types (formats) of the model. "component": { "type": "machine-learning-model", - ... + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", + ..., "modelCard": { - ... + ..., "inputs": [ {"format": "string"} ], @@ -324,66 +327,6 @@ Describes the input and output data types (formats) of the model. } ``` - ---- - -### Complete model card example - -###### Example: CycloneDX Model Card for the Qwen-7B model - -Again, we continue to showcase the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model from Hugging Face. You may follow the link to its home page in Hugging Face which should show you its [README.md]() file which contains some structured, but mostly unstructured model card information to see how it is translated to CycloneDX objects and schema. - -```json -"modelCard": { - "modelParameters": { - "approach": { - "type": "supervised" - }, - "task": "task goes here", - "architectureFamily": "the architecture family goes here", - "modelArchitecture": "The architecture of the model.", - "datasets": [ - { - "type": "dataset", - "name": "Training Data", - "contents": { - "url": "https://example.com/path/to/dataset" - }, - "classification": "public" - } - ], - }, - - "considerations": { - "users": [ - "Who are the intended users of the model?" - ], - "useCases": [ - "Who are the intended users of the model?" - ], - "technicalLimitations": [ - "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?" - ], - "performanceTradeoffs": [ - "What are the known tradeoffs in accuracy/performance of the model?" - ], - "ethicalConsiderations": [ - { - "name": "The name of the risk", - "mitigationStrategy": "Strategy used to address this risk" - } - ], - "fairnessAssessments": [ - { - "groupAtRisk": "The groups or individuals at risk of being systematically disadvantaged by the model", - "benefits": "Expected benefits to the identified groups", - "harms": "Expected harms to the identified groups", - "mitigationStrategy": "With respect to the benefits and harms outlined, please describe any mitigation strategy implemented." - } - ] - } -} -``` --- ### Declaring other properties From 42d2c3caa7643069a949cba333d9f85993708a94 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 23 Jan 2026 11:26:37 -0600 Subject: [PATCH 037/111] Author the Model Card Parameters sections Signed-off-by: Matt Rutkowski --- ...Design-Model-Card-Quantitative-Analysis.md | 120 +++++++++++++----- 1 file changed, 88 insertions(+), 32 deletions(-) diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index a50b31f..024214d 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -11,55 +11,111 @@ This section will feature guidance on filling out information in the Cyclone mod --- -# What is quantitative analysis +### What is quantitative analysis A quantitative analysis of an AI model involves using mathematical and statistical methods to objectively measure and evaluate its performance, behavior, and outputs using numerical data, focusing on how much or how often, unlike qualitative analysis which looks at why. It assesses metrics like accuracy, precision, recall, efficiency, and consistency, transforming raw data into verifiable insights to understand patterns, test hypotheses, and ensure reliability for decision-making, moving beyond subjective human interpretation. -#### Key Aspects of Quantitative AI Analysis: +#### The value of quantitative analysis -* **Numerical Metrics**: Uses measurable data (e.g., error rates, latency, performance scores) rather than subjective feedback. -* **Performance Benchmarking**: Calculates specific scores (like F1-score, AUC, BLEU for LLMs) to compare models rigorously. +* **Numerical Metrics**: Provides measurable data (e.g., error rates, latency, performance scores) rather than subjective feedback. * **Objective Evaluation**: Provides reproducible, scalable results that can be compared across different models or versions. -* **Pattern & Trend Detection**: Identifies numerical patterns, correlations, and trends within large datasets that might be missed manually. -* **Testing Hypotheses**: Statistically tests assumptions about model behavior (e.g., "Does Model X consistently outperform Model Y on this task?"). -* **Automation**: AI itself can automate complex quantitative analysis, handling vast amounts of data and uncovering intricate relationships. +* **Pattern & Trend Detection**: Identifies numerical patterns, correlations, and trends within large or complex datasets that might be missed manually. +* **Testing Hypotheses**: Enables the statistical testing of assumptions about model behavior allowing for comparisons against similar models for given tasks. + +--- + +### Performance metrics + +Describes any standardized metrics and evaluations used to measure and compare the effectiveness, efficiency and output correctness of a model providing a crucial, objective way to determine which model is best suited for a particular task or deployment environment. + +> [!Note] Currently, CycloneDx supports declaring metrics in the area of *performance benchmarks* which is the most consistently seen set of named metrics described within model cards today. + +#### Types of machine learning benchmarks + +ML model performance benchmarks use standardized datasets (like ImageNet, GLUE) and metrics (Accuracy, F1 Score, MMLU) to objectively compare model quality, efficiency, fairness, and speed, providing a shared ruler for progress, reproducibility, and identifying areas for improvement in fields like Computer Vision and NLP. [1, 2, 3, 4] +Key Types of Benchmarks + +• Task-Specific Benchmarks: Standardized datasets for common tasks (e.g., MNIST for digits, CIFAR-10 for images, IMDb for sentiment). +• System Benchmarks (MLPerf): Evaluate hardware (GPUs, TPUs) and software infrastructure for training and inference speed. +• Model-Specific Benchmarks: Assess different aspects of model quality, from basic metrics to advanced reasoning. [1, 3, 5, 6] + +Common Performance Metrics + +• Classification: + + • Accuracy: Overall correctness. + • Precision: Of predicted positives, how many are correct. + • Recall (Sensitivity): Of actual positives, how many are found. + • F1 Score: Harmonic mean of Precision and Recall. + • ROC AUC: Area under the Receiver Operating Characteristic curve. + +• Large Language Models (LLMs): + + • MMLU: Measures knowledge across many subjects. + • HellaSwag: Tests commonsense reasoning. + • TruthfulQA: Assesses truthfulness in responses. + +• Efficiency: + + • Latency/Throughput: Speed of prediction (inference). + • Resource Utilization: Memory, CPU/GPU usage. [2, 3, 4, 5] + +Why Benchmarking Matters + +• Fair Comparison: Enables objective comparison between different algorithms and models. +• Drives Progress: Identifies state-of-the-art (SOTA) performance and pushes innovation. +• Reproducibility: Ensures results can be verified and replicated. +• Transparency: Helps communicate AI value to stakeholders. [1, 3, 7, 8, 9, 10] + +Examples of Benchmarks & Datasets + +• Computer Vision: ImageNet, CIFAR. +• NLP: GLUE, SuperGLUE, SQuAD, MMLU. +• Repositories: Kaggle, UCI Machine Learning Repository, OpenML, {Milvus](https://milvus.io/ai-quick-reference/what-are-benchmark-datasets-in-machine-learning-and-where-can-i-find-them) https://milvus.io/ai-quick-reference/what-are-benchmark-datasets-in-machine-learning-and-where-can-i-find-them), TensorFlow Datasets, TorchVision. [1, 4, 6, 11] + +AI responses may include mistakes. + +[1] https://labelstud.io/learningcenter/what-are-benchmarks/ +[2] https://www.ibm.com/think/topics/model-performance +[3] https://mlcommons.org/benchmarks/ +[4] https://www.teqfocus.com/blog/benchmarking-large-language-models-a-comprehensive-guide/ +[5] https://coe-379l-sp24.readthedocs.io/en/latest/unit04/ml_benchmarks.html +[6] https://milvus.io/ai-quick-reference/what-are-benchmark-datasets-in-machine-learning-and-where-can-i-find-them +[7] https://www.tutorialspoint.com/what-are-the-machine-learning-benchmarks +[8] https://www.youtube.com/watch?v=_lmT4Nqtm-A +[9] https://help.pecan.ai/en/articles/7338218-understanding-pecan-s-benchmarks +[10] https://www.emergentmind.com/topics/benchmarking-machine-learning-algorithms +[11] https://www.meegle.com/en_us/topics/ai-model-evaluation/ai-model-benchmarking ---- -#### Performance metrics ```json -{ - "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... - "metadata": + "component": { - "component": - { - "type": "machine-learning-model", + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", + ..., + ... + "modelCard": { ... - "modelCard": { - ... - "quantitativeAnalysis": { - "performanceMetrics": [ - { - "type": "benchmark_score", - "value": "The value of the performance metric", - // "slice": "The name of the slice this metric was computed on. By default, assume this metric is not sliced", - "slice": "Specific benchmark name (e.g., MMLU, GSM8K)" - "confidenceInterval": { - "lowerBound": "The lower bound of the confidence interval", - "upperBound": "The upper bound of the confidence interval" - } + "quantitativeAnalysis": { + "performanceMetrics": [ + { + "type": "benchmark_score", + "value": "The value of the performance metric", + // "slice": "The name of the slice this metric was computed on. By default, assume this metric is not sliced", + "slice": "Specific benchmark name (e.g., MMLU, GSM8K)" + "confidenceInterval": { + "lowerBound": "The lower bound of the confidence interval", + "upperBound": "The upper bound of the confidence interval" } - ] - } + } + ] } } } -} ``` #### Graphics From ab34529815f4d736272928a0372e527b39ff80a6 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 23 Jan 2026 15:31:00 -0600 Subject: [PATCH 038/111] Author the Model Card Parameters sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x21-Design-Model-Card-Overview.md | 21 ++++++++++++------- .../en/0x22-Design-Model-Card-Parameters.md | 17 +++++++-------- ...Design-Model-Card-Quantitative-Analysis.md | 3 ++- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/ML-BOM/en/0x21-Design-Model-Card-Overview.md b/ML-BOM/en/0x21-Design-Model-Card-Overview.md index 07603f2..da2f774 100644 --- a/ML-BOM/en/0x21-Design-Model-Card-Overview.md +++ b/ML-BOM/en/0x21-Design-Model-Card-Overview.md @@ -15,14 +15,19 @@ For convenience, here are links to the specific sections for each of those infor >[!TODO] add hyperlinks when done with all subsections - [Model parameters](0x22-Design-Model-Card-Parameters.md#model-parameters) - - [Model architecture]() - - [Approach & tasks]() - - [Datasets]() - - [Inputs & Outputs]() - - [Tokenizers and prompt templates]() - -- [Quantitative analysis]() - - [Performance metrics & graphics]() + - [Model metadata](0x22-Design-Model-Card-Parameters.md#model-metadata) + - [Approach](0x22-Design-Model-Card-Parameters.md#approach) + - [Task](0x22-Design-Model-Card-Parameters.md#task) + - [Architecture family](0x22-Design-Model-Card-Parameters.md#architecture-family) + - [Model architecture](0x22-Design-Model-Card-Parameters.md#model-architecture) + - [Datasets](0x22-Design-Model-Card-Parameters.md#datasets) + - [Inputs & Outputs](0x22-Design-Model-Card-Parameters.md#inputs--outputs) + - [Declaring other properties](0x22-Design-Model-Card-Parameters.md#declaring-other-properties) + - [Configuration parameters & hyperparameters](0x22-Design-Model-Card-Parameters.md#configuration-parameters--hyperparameters) + +- [Quantitative analysis](0x23-Design-Model-Card-Quantitative-Analysis.md#quantitative-analysis) + - [Performance metrics](0x23-Design-Model-Card-Quantitative-Analysis.md#performance-metrics) + - [Graphics](0x23-Design-Model-Card-Quantitative-Analysis.md#graphics) - [Considerations]() - [Users & use cases]() diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index 6e317ad..fee55a7 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -71,9 +71,7 @@ Again, the list above represents architecture families that are commonly referen #### Model architecture -TODO - -The model architecture field is intended to include a specific keywords to identify an implementation (class or library) or technical descriptors of the architectural "blueprint" needed to run a specific model. +The model architecture field is intended to include specific keywords to identify an implementation (class or library) or technical descriptors of the architectural "blueprint" needed to run a specific model. These are typically found in one of several locations relative to the model: @@ -117,7 +115,7 @@ This example shows best practice for the Qwen-7B model using information publish * **modelArchitecture** - the value `QWenLMHeadModel` was located in the model's `config.json` model configuration file. -#### External references +#### Providing links to papers & articles Most models are fully described in terms of research papers, articles and other reference documents. In those cases, they should be provided as `externalReferences` under the `component`. @@ -167,7 +165,7 @@ Specifically, the component `modelCard` object includes `modelParameters` which The next sections will discuss the considerations for each and example how to use both of these methods. -#### In-line information +##### Datasets as in-line information This method simplifies the association between training datasets and model cards, specifically addressing scenarios where data is difficult to reference as an independent component. @@ -177,8 +175,7 @@ Key applications: * **Private Repositories**: Providing transparency via BOMs for non-public datasets in public model cards (e.g, private data used for models in the healthcare or financial services industries). * **Unstructured Sources**: Referencing data not housed in traditional databases or management tools (e.g., data within S3 buckets, event data within Security information and event management (SIEM) systems). - -##### Example: Custom health model with private dataset +###### Example: Custom health model with private dataset This example shows a model fine-tuned (by a fictional "ACME Health" company) from the public [m42-health/Llama3-Med42-8B](https://huggingface.co/m42-health/Llama3-Med42-8B) model using a private dataset. @@ -228,11 +225,11 @@ back dataset", } ``` -#### Data component references +##### Datasets as data component references This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information as a full, CycloneDX component. -##### Example: health model with private dataset +###### Example: health model with private dataset This example shows the recommended best practice of declaring the datasets for the base model used in the previous "in-line" example (i.e., [m42-health/Llama3-Med42-8B](https://huggingface.co/m42-health/Llama3-Med42-8B)) as their own CycloneDX components. @@ -331,7 +328,7 @@ In order to provide information on model parameters and hyperparameters using ex ### Declaring other properties -#### Configuration Parameters & hyperparameters +#### Configuration parameters & hyperparameters In general, model configuration parameters describe values that are directly used to configure model processing applications and frameworks and their implementations of model architectures. For example, most models that appear in Hugging Face typically include configuration files for both the models and the tokenizers they are designed for use with the [Hugging Face Transformers](https://huggingface.co/docs/transformers/) library and its underlying use of the PyTorch framework. diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 024214d..6cae5ab 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -117,12 +117,13 @@ AI responses may include mistakes. } } ``` +--- #### Graphics TODO -### Quantitative analysis +### Example: Graphis ```json { From acce7b9225d560925fe88c8ea1c30215449f8df4 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 23 Jan 2026 17:13:43 -0600 Subject: [PATCH 039/111] Author the Model Card Parameters sections Signed-off-by: Matt Rutkowski --- .../0x24-Design-Model-Card-Considerations.md | 114 +++++++++++++++++- 1 file changed, 110 insertions(+), 4 deletions(-) diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 3e2d594..d18b94d 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -8,10 +8,11 @@ This section will feature guidance on filling out information in the Cyclone mod This section will feature guidance on filling out information in the Cyclone model card's `modelParameters` object and its subcomponents including: -* [Users](#users) -* [Use cases](#use-cases) -* [Technical limitations](#technical-limitations) -* [Performance Tradeoffs](#performance-tradeoffs) +* [Users](#users) - Who are the intended users of the model? +* [Use cases](#use-cases) - What are the intended use cases of the model? +* [Technical limitations](#technical-limitations) - What are the known technical limitations of the model? For example, "What kind(s) of data should the model be expected not to perform well on?", "What are the factors that might degrade model performance?". +* [Performance tradeoffs](#performance-tradeoffs) - What are the known tradeoffs in accuracy/performance of the model? +* [Ethical considerations]() - What are the ethical risks involved in the application of this model? * [Fairness assessments](#fairness-assessments) * [Environmental considerations](#environmental-considerations) @@ -19,6 +20,12 @@ This section will feature guidance on filling out information in the Cyclone mod ### Users +Used to provide list describing the intended users of the model. + +```json + +``` + --- ### Use cases @@ -31,6 +38,16 @@ This section will feature guidance on filling out information in the Cyclone mod ### Performance Tradeoffs +--- + +### Ethical considerations + +#### Name + + +#### Mitigation strategy + + --- ### Fairness assessments @@ -39,6 +56,95 @@ This section will feature guidance on filling out information in the Cyclone mod ### Environmental considerations +#### Energy consumptions + +> [!Note] Although trained models are often published publicly for consumption most of the providers do not currently disclose the costs of training their models. This section describes how providers could do so at different stages of the model's lifecycle in order to address potential governmental regulations and requirements. This information may include disclosure CO2 emission costs and CO2 offsets (credits). + +##### Activity + +The type of activity that is part of a machine learning model development or operational lifecycle that has an associated energy consumption. + +| Value | Description | +|---|---| +| **design** | A model design including problem framing, goal definition and algorithm selection.| +| **data-collection** |Model data acquisition including search, selection and transfer.| +| **data-preparation** | Model data preparation including data cleaning, labeling and conversion. | +| **training** | Model building, training and generalized tuning. | +| **fine-tuning** | Refining a trained model to produce desired outputs for a given problem space. | +| **validation** | Model validation including model output evaluation and testing. | +| **deployment** | Explicit model deployment to a target hosting infrastructure. | +| **inference** | Generating an output response from a hosted model from a set of inputs. | +| **other** | A lifecycle activity type whose description does not match currently defined values. | + +##### Energy providers + +##### Activity energy cost + +##### CO2 cost equivalent + +##### CO2 cost offset + + +###### Example: + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.7", + "serialNumber": "urn:uuid:ed5c5ba0-2be6-4b58-ac29-01a7fd375123", + "version": 1, + "components": [ + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Fake-llama/Llama3-7B@abcd123", + ..., + "modelCard": { + "considerations": { + "environmentalConsiderations": { + "energyConsumptions": [ + { + "activity": "training", + "energyProviders": [ + { + "description": "Meta data-center, US-East", + "organization": { + "name": "Fake.ai", + "address": { + "country": "United States", + "region": "New Jersey", + "locality": "Newark" + } + }, + "energySource": "natural-gas", + "energyProvided": { + "value": 0.4, + "unit": "kWh" + } + } + ], + "activityEnergyCost": { + "value": 0.4, + "unit": "kWh" + }, + "co2CostEquivalent": { + "value": 31.22, + "unit": "tCO2eq" + }, + "co2CostOffset": { + "value": 31.22, + "unit": "tCO2eq" + } + } + ] + } + } + } + } + ] +} +``` + ---
From 0fe6472d355e0ae7b84700d0ea2e00030f792fff Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 23 Jan 2026 17:35:26 -0600 Subject: [PATCH 040/111] Author the Energy Consumption sections Signed-off-by: Matt Rutkowski --- .../0x24-Design-Model-Card-Considerations.md | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index d18b94d..c8ccfea 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -58,7 +58,18 @@ Used to provide list describing the intended users of the model. #### Energy consumptions -> [!Note] Although trained models are often published publicly for consumption most of the providers do not currently disclose the costs of training their models. This section describes how providers could do so at different stages of the model's lifecycle in order to address potential governmental regulations and requirements. This information may include disclosure CO2 emission costs and CO2 offsets (credits). +This section describes how model providers can publish the energy costs incurred during different stages of the model's lifecycle in order to address potential governmental regulations and requirements. This information includes the energy sources (i.e., for the datacenters) as well as disclosure of CO2 emission cost equivalents and CO2 offsets (credits). + +The intent is for CycloneDX to be able to support the general requirements referenced by the [EU’s AI Act](https://eur-lex.europa.eu/eli/reg/2024/1689/oj/eng) which refers to ‘environmental protection’ in its subject matter. + +Summary of EU AI Act Environmental Disclosure Rules for GPAI Models: + +* **Requirement**: Providers of General-Purpose AI (GPAI) models must disclose the known or estimated energy consumption used during their model's development. + * *This information is provided only upon request to the EU's AI Office and national competent authorities.* +* **Reference**: These requirements are outlined in [Article 53](https://artificialintelligenceact.eu/article/53/) and [Annex XI](https://artificialintelligenceact.eu/annex/11/) of the [EU AI Act](https://eur-lex.europa.eu/eli/reg/2024/1689/oj/eng). +* **Exemption**: Models released under a free and open-source license are exempt from this disclosure obligation. + +> [!Note] Since most trained models are published under some form of open license, most providers do not currently disclose the costs of training their models. ##### Activity @@ -87,6 +98,8 @@ The type of activity that is part of a machine learning model development or ope ###### Example: + + ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", @@ -97,7 +110,7 @@ The type of activity that is part of a machine learning model development or ope "components": [ { "type": "machine-learning-model", - "bom-ref": "pkg:huggingface/Fake-llama/Llama3-7B@abcd123", + "bom-ref": "pkg:huggingface/FakeAI/Llama3@abcd123", ..., "modelCard": { "considerations": { @@ -145,6 +158,10 @@ The type of activity that is part of a machine learning model development or ope } ``` +###### Field notes + +* **unit** - the unit `tCO2eq` is defined by the European Commission and stands for metric tonnes of carbon dioxide equivalent, a standardized unit used to measure the total greenhouse gas emissions (including methane and nitrous oxide) generated during the development, training, and operation of AI systems. + ---
From 0234552994b6dbdf5f46d7998768b4c64f4a739d Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 26 Jan 2026 10:04:35 -0600 Subject: [PATCH 041/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x24-Design-Model-Card-Considerations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index c8ccfea..29a759c 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -13,8 +13,8 @@ This section will feature guidance on filling out information in the Cyclone mod * [Technical limitations](#technical-limitations) - What are the known technical limitations of the model? For example, "What kind(s) of data should the model be expected not to perform well on?", "What are the factors that might degrade model performance?". * [Performance tradeoffs](#performance-tradeoffs) - What are the known tradeoffs in accuracy/performance of the model? * [Ethical considerations]() - What are the ethical risks involved in the application of this model? -* [Fairness assessments](#fairness-assessments) -* [Environmental considerations](#environmental-considerations) +* [Fairness assessments](#fairness-assessments) - How does the model affect groups at risk of being systematically disadvantaged? What are the harms and benefits to the various affected groups? +* [Environmental considerations](#environmental-considerations) - What are the various environmental impacts the corresponding machine learning model has exhibited across its lifecycle? --- From 7a8767317cb1c22e4a6c8357a58a239f93f94cfa Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 26 Jan 2026 11:03:55 -0600 Subject: [PATCH 042/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x91-Appendix-B_References.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index 0efb7fd..82e0506 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -60,6 +60,7 @@ Huggingface model (repositories) typically support the `.safetensors` Huggingfac * [microsoft/resnet-50](https://huggingface.co/microsoft/resnet-50/blob/main/README.md) - single `model.safetensors`, `pytorch_model.bin` file. * [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) - multiple `*.safetensors` files with `model.safetensors.index.json` index. + * [ArXiv - Qwen3 Technical Report (summary)](https://arxiv.org/html/2505.09388.pdf) ##### Kaggle From 76bb05632074454418b310f09d8c6f1583039773 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 26 Jan 2026 15:09:29 -0600 Subject: [PATCH 043/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...Design-Model-Card-Quantitative-Analysis.md | 1 - .../0x24-Design-Model-Card-Considerations.md | 41 ++++++++++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 6cae5ab..6e523e6 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -97,7 +97,6 @@ AI responses may include mistakes. "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", ..., - ... "modelCard": { ... "quantitativeAnalysis": { diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 29a759c..da334db 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -18,17 +18,48 @@ This section will feature guidance on filling out information in the Cyclone mod --- -### Users +### Users & use cases -Used to provide list describing the intended users of the model. +Used to provide list describing the intended users of the model along with a list of envisioned use cases for the model. -```json +###### Example: Qwen3/Qwen-7B + +This example shows a list for what kind of information would be expected for a typical `7B` parameter size Large Language Model (LLM) that is multi-lingual and supports code/instruct capabilities. + +```json +"component": { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", + ..., + "modelCard": { + ..., + "considerations": { + "users": [ + "Software developer", + "Multilingual Content Creator", + "Customer Support Systems Architect", + "Academic Researcher / Student", + "Edge Device Engineer", + "Enterprise Security Analyst", + "Local AI Enthusiast / Privacy-First User" + ], + "useCases": [ + "Utilizing the Qwen3-Coder variant within an IDE for real-time code completion, bug fixing, and unit test generation, benefiting from its \"Agentic\" capabilities for repository-scale understanding.", + "Translating business, education or other content or informational materials to other languages and dialects while maintaining the original tone and cultural nuances.", + "Deploying low-latency chatbots for high-volume inquiries where the 7B model acts as a \"triage\" agent, answering common questions and only escalating complex logic to other support mechanisms.", + "Summarizing long-form research papers and generating initial drafts for school projects, utilizing the model's 128K context window to ingest entire PDFs at once.", + "Implementing the model on specialized hardware for real-time visual perception and \"Thinking Mode\" reasoning to help an intelligent device navigate and interact with its environment based on natural language commands", + "Running a self-hosted instance to analyze internal security logs for anomalies, ensuring that sensitive infrastructure data never leaves the organization's firewall.", "Running a personal assistant locally on a laptop to answer questions or process private information such as emails or calendars without sending data to an external server." + ], + } + } +} ``` ---- +###### Field notes -### Use cases +* There is no expectation that there is a 1:1 correlation between `users` and `useCases` entries. However, there should be at least one listed use cases that can correspond to a named "user" (role). --- From 39227d53beae5894799b7ef3c6b9f6d0388be41c Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 26 Jan 2026 15:17:00 -0600 Subject: [PATCH 044/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- .../0x24-Design-Model-Card-Considerations.md | 99 ++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index da334db..2ba5f9a 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -25,7 +25,7 @@ Used to provide list describing the intended users of the model along with a lis ###### Example: Qwen3/Qwen-7B -This example shows a list for what kind of information would be expected for a typical `7B` parameter size Large Language Model (LLM) that is multi-lingual and supports code/instruct capabilities. +This example shows a list for what kind of user and use case information would be expected for a typical `7B` parameter size Large Language Model (LLM) that is multi-lingual and supports code/instruct capabilities. ```json "component": { @@ -65,10 +65,56 @@ This example shows a list for what kind of information would be expected for a t ### Technical limitations +This example shows a list for what kind of technical limitations might be assocated with a typical Large Language Model (LLM) that is multi-lingual and supports code/instruct capabilities with similar (i.e., ~`8B`) parameter size. + +```json +"component": { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", + ..., + "modelCard": { + ..., + "considerations": { + "technicalLimitations": [ + "", + "", + "", + "", + "", + "", + "" + ] + } + } +} +``` + --- ### Performance Tradeoffs +```json +"component": { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", + ..., + "modelCard": { + ..., + "considerations": { + "performanceTradeoffs": [ + "", + "", + "", + "", + "", + "", + "" + ] + } + } +} +``` + --- ### Ethical considerations @@ -78,11 +124,62 @@ This example shows a list for what kind of information would be expected for a t #### Mitigation strategy +```json +"component": { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", + ..., + "modelCard": { + ..., + "considerations": { + "ethicalConsiderations": [ + { + "name": "", + "mitigationStrategy": "" + }, + { + "name": "", + "mitigationStrategy": "" + }, + ... + ] + } + } +} +``` --- ### Fairness assessments +```json +"component": { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", + ..., + "modelCard": { + ..., + "considerations": { + "fairnessAssessments": [ + { + "groupAtRisk": "", + "benefits": "", + "harms": "", + "mitigationStrategy": "" + }, + { + "groupAtRisk": "", + "benefits": "", + "harms": "", + "mitigationStrategy": "" + }, + ... + ] + } + } +} +``` + --- ### Environmental considerations From dadbe4ca8f22eed006c263841ff6e139e32a7260 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 26 Jan 2026 17:18:42 -0600 Subject: [PATCH 045/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x24-Design-Model-Card-Considerations.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 2ba5f9a..48bdc96 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -65,7 +65,7 @@ This example shows a list for what kind of user and use case information would b ### Technical limitations -This example shows a list for what kind of technical limitations might be assocated with a typical Large Language Model (LLM) that is multi-lingual and supports code/instruct capabilities with similar (i.e., ~`8B`) parameter size. +This example shows a list for what kind of technical limitations might be associated with a typical Large Language Model (LLM) that is multi-lingual and supports code/instruct capabilities with similar (i.e., ~`8B`) parameter size. ```json "component": { @@ -76,13 +76,10 @@ This example shows a list for what kind of technical limitations might be assoca ..., "considerations": { "technicalLimitations": [ - "", - "", - "", - "", - "", - "", - "" + "Greedy Decoding Degradation. The model is optimized for sampling-based generation. Using greedy decoding (temperature=0) can lead to performance degradation, repetitive loops, and "stuck" reasoning steps, particularly in the new Thinking Mode", + "Native Context Window Boundaries. While the model supports up to 131,072 tokens using YaRN scaling, its native pre-training context is limited to 32,768 tokens. Performance may degrade on very long sequences if proper scaling factors (like RoPE or YaRN) are not manually configured for local deployments.", + "Synthetic Data \"Sanding\" Effects. Research indicates that Qwen3, like many models trained on massive synthetic datasets, can suffer from \"model collapse\" where rare edge cases or minority user behaviors are underrepresented, potentially leading to errors in complex, real-world production environments.", + "Thinking Mode History Overhead. In multi-turn conversations, including the model's internal \"thinking\" steps in the chat history can confuse the model and consume unnecessary tokens. Best practices require developers to filter out \"thinking\" content from the history to maintain coherence." ] } } From d44679e7905f883ba108025597a93d94ab07ebc2 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 26 Jan 2026 17:34:05 -0600 Subject: [PATCH 046/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- .../0x24-Design-Model-Card-Considerations.md | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 48bdc96..2798416 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -99,13 +99,13 @@ This example shows a list for what kind of technical limitations might be associ ..., "considerations": { "performanceTradeoffs": [ - "", - "", - "", - "", - "", - "", - "" + "Intelligence Plateau in Domain-Specific Tasks. Research indicates that for specialized fields like legal text analysis, performance often flattens beyond the 7B parameter mark. While efficient, the 7B model may not offer the incremental reasoning gains found in the 32B or 235B models for complex, high-stakes domain reasoning.", + "Enhanced Quantization Sensitivity. The Qwen3-7B employs advanced pre-training techniques that reduce parameter redundancy. A documented tradeoff of this efficiency is a higher sensitivity to low-bit quantization (3-bit and below), where it exhibits more pronounced performance degradation compared to previous 7B generations.", + "Context Window Consistency. While the 7B model supports a native context window of 32,768 tokens, its performance degrades significantly more than the Qwen3-8B (which uses YaRN scaling to reach 128K+) when handling massive document sets. Users must tradeoff deep long-document comprehension for the 7B's lower memory footprint.", + "Conciseness vs. Contextual Nuance. Experiments show that the older 7B design prioritizes cleaner, easier-to-read, and more concise outputs. The tradeoff is a loss of the \"faithful and nuanced\" insights and richer context provided by the newer 8B and larger architectures.", + "Agentic Capability Limitations. The 7B model shows a documented gap in its ability to follow complex multi-step instructions or navigate large software repositories, requiring tighter chunking and more finely tuned prompts to be effective", + "Hardware Efficiency vs. Throughput. Running the 7B model on older hardware (e.g., 8GB VRAM cards) is possible but results in a tradeoff of throughput. Modern inference techniques like continuous batching and PagedAttention are less effective at this scale than on the larger, more parallelizable MoE models.", + "Decoding Strategy Rigidity. The 7B model is highly sensitive to sampling parameters; specifically, using greedy decoding (temperature=0) can lead to severe repetition loops and \"endless repetitions\". To maintain performance, users must tradeoff predictability for more complex sampling-based generation." ] } } @@ -131,12 +131,28 @@ This example shows a list for what kind of technical limitations might be associ "considerations": { "ethicalConsiderations": [ { - "name": "", - "mitigationStrategy": "" + "name": "Algorithmic and Cultural Bias. As a model trained on 36 trillion tokens across 119 languages, Qwen3-7B may still reflect societal biases, stereotypes, or representational harms present in its training data.", + "mitigationStrategy": "Use the Qwen-Gender framework or Chain-of-Thought (CoT) prompting to detect and reduce implicit biases in generated text." }, { - "name": "", - "mitigationStrategy": "" + "name": "Vulnerability to Adversarial Attacks (Jailbreaking). Despite safety tuning, the 7B model can be susceptible to \"Prompt Hacking\" or \"Jailbreaking\" where users bypass safety constraints to generate toxic or illegal content.", + "mitigationStrategy": "Implement Qwen3Guard as an input/output filter to classify and block unsafe queries or responses in real-time" + }, + { + "name": "Misinformation or Hallucinations. The model can fabricate false or misleading information, especially regarding sensitive topics like government actions or historical events.", + "mitigationStrategy": "Explicitly instruct the model to \"Prioritize Safety\" in the prompt and use Retrieval-Augmented Generation (RAG) to ground responses in verified external documents." + }, + { + "name": "Privacy, Sensitive or Personally Identifiable Information (PII)Content Leakage. If such data was present in the pre-training corpus, this risk for generation od such data is possible.", + "mitigationStrategy": "Deploy the model locally using tools like Ollama to ensure sensitive data stays within a secure environment, and apply regex-based PII scrubbing to outputs." + }, + { + "name": "Environmental Impact (Inference Energy). Continuous large-scale deployment of even mid-sized models like the 7B contributes to significant energy consumption and carbon footprints.", + "mitigationStrategy": "Utilize 4-bit quantization and low-latency inference engines to reduce the FLOPs required per token, minimizing the power draw per query." + }, + { + "name": "Instruction Misalignment. In-context learning can sometimes lead to \"emergent misalignment\", where the model prioritizes following a user's conversational style over established safety boundaries.", + "mitigationStrategy": "Standardize output formats using system prompts and utilize the \"hard switch\" to disable the model's internal thinking mode when maximum safety and predictability are required." }, ... ] From dda2135981530e495df084c0e7213a1767e6a731 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 26 Jan 2026 17:43:37 -0600 Subject: [PATCH 047/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x24-Design-Model-Card-Considerations.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 2798416..e5fc645 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -22,7 +22,6 @@ This section will feature guidance on filling out information in the Cyclone mod Used to provide list describing the intended users of the model along with a list of envisioned use cases for the model. - ###### Example: Qwen3/Qwen-7B This example shows a list for what kind of user and use case information would be expected for a typical `7B` parameter size Large Language Model (LLM) that is multi-lingual and supports code/instruct capabilities. @@ -116,10 +115,16 @@ This example shows a list for what kind of technical limitations might be associ ### Ethical considerations -#### Name +Used to provide list describing known ethical considerations when using a model. Each consideration is an object containing two fields: + +* **Name** - A concise name for the ethical considerations. +* **Mitigation strategy** - A corresponding (recommended) mitigation strategy, for the named consideration, to take when using the model. + +> [!Note] Since there is no agreed-upon standard for ethical considerations we recommend using the `name` field to additionally provide further description to clarify the name as needed. +###### Example: Qwen3-7B ethical considerations -#### Mitigation strategy +Based on technical reports and safety evaluations such as Qwen3Guard, the following ethical considerations and mitigations are documented and typical of a multi-lingual LLM of similar parameter size and with a dense architecture: ```json "component": { From d3b4ffbf603cf804c1aa0363c25472333b3c45c8 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 28 Jan 2026 08:44:33 -0600 Subject: [PATCH 048/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x22-Design-Model-Card-Parameters.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index fee55a7..53e877c 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -225,6 +225,10 @@ back dataset", } ``` +###### Field notes + +* **url** - Please note that URLs may be to either public or private resources. For example, in the case of the ACME `private` dataset above, the URL is likely behind an Access Control Point (ACP) which regulates traffic to the private resource in accordance with the ACME company's governance policies. + ##### Datasets as data component references This method is preferable for use in most security and compliance contexts as it allows for full expression of provenance, pedigree, attestations and other contextual information as a full, CycloneDX component. From 6f5bd3fd0cbfd1fe828c95c49fcd875f10fd98cd Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 28 Jan 2026 10:00:36 -0600 Subject: [PATCH 049/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...-Card-Overview.md => 0x20-Design-Model-Card-Overview.md} | 0 ...-Metadata.md => 0x21-Design-Model-Component-Metadata.md} | 0 ML-BOM/en/0x85-Appendix-1-Examples.md | 6 ++++-- 3 files changed, 4 insertions(+), 2 deletions(-) rename ML-BOM/en/{0x21-Design-Model-Card-Overview.md => 0x20-Design-Model-Card-Overview.md} (100%) rename ML-BOM/en/{0x20-Design-Model-Component-Metadata.md => 0x21-Design-Model-Component-Metadata.md} (100%) diff --git a/ML-BOM/en/0x21-Design-Model-Card-Overview.md b/ML-BOM/en/0x20-Design-Model-Card-Overview.md similarity index 100% rename from ML-BOM/en/0x21-Design-Model-Card-Overview.md rename to ML-BOM/en/0x20-Design-Model-Card-Overview.md diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x21-Design-Model-Component-Metadata.md similarity index 100% rename from ML-BOM/en/0x20-Design-Model-Component-Metadata.md rename to ML-BOM/en/0x21-Design-Model-Component-Metadata.md diff --git a/ML-BOM/en/0x85-Appendix-1-Examples.md b/ML-BOM/en/0x85-Appendix-1-Examples.md index 0edb2e7..5c73759 100644 --- a/ML-BOM/en/0x85-Appendix-1-Examples.md +++ b/ML-BOM/en/0x85-Appendix-1-Examples.md @@ -1,6 +1,8 @@ -# Appendix 1: Examples +# Appendix 1: Complete ML-BOM example -## Full ML-BOM example +## Qwen/Qwen-7B ML-BOM + +Throughout this guide provided incremental examples were shown of how to fill out various parts of an ML-BOM using the [Qwen3-7B](https://huggingface.co/Qwen/Qwen-7B) model. This section brings those together to show what a complete ML-BOM would look like for that model. ```json { From 71dd3daff73cb3bb2e096cc2f965f192623eb3a2 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 28 Jan 2026 16:36:20 -0600 Subject: [PATCH 050/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...> 0x20-Design-Model-Component-Metadata.md} | 0 ....md => 0x21-Design-Model-Card-Overview.md} | 24 ++++++++-------- .../0x24-Design-Model-Card-Considerations.md | 28 +++++++++++++++---- ...40-Design-Additional-Model-Information.md} | 19 ++++++++++++- ML-BOM/en/0x91-Appendix-B_References.md | 13 +++++++-- 5 files changed, 65 insertions(+), 19 deletions(-) rename ML-BOM/en/{0x21-Design-Model-Component-Metadata.md => 0x20-Design-Model-Component-Metadata.md} (100%) rename ML-BOM/en/{0x20-Design-Model-Card-Overview.md => 0x21-Design-Model-Card-Overview.md} (71%) rename ML-BOM/en/{0x40-Design-Other.md => 0x40-Design-Additional-Model-Information.md} (72%) diff --git a/ML-BOM/en/0x21-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md similarity index 100% rename from ML-BOM/en/0x21-Design-Model-Component-Metadata.md rename to ML-BOM/en/0x20-Design-Model-Component-Metadata.md diff --git a/ML-BOM/en/0x20-Design-Model-Card-Overview.md b/ML-BOM/en/0x21-Design-Model-Card-Overview.md similarity index 71% rename from ML-BOM/en/0x20-Design-Model-Card-Overview.md rename to ML-BOM/en/0x21-Design-Model-Card-Overview.md index da2f774..0eced21 100644 --- a/ML-BOM/en/0x20-Design-Model-Card-Overview.md +++ b/ML-BOM/en/0x21-Design-Model-Card-Overview.md @@ -29,17 +29,19 @@ For convenience, here are links to the specific sections for each of those infor - [Performance metrics](0x23-Design-Model-Card-Quantitative-Analysis.md#performance-metrics) - [Graphics](0x23-Design-Model-Card-Quantitative-Analysis.md#graphics) -- [Considerations]() - - [Users & use cases]() - - [Technical limitations]() - - [Performance tradeoffs]() - - [Fairness assessments]() - - [Intended use & ethics]() - - [Environmental impacts]() - -- [Other]() - - [Hardware, software & frameworks]() - - [Training & testing details]() +- [Considerations](0x24-Design-Model-Card-Considerations.md#considerations) + - [Users & use cases](0x24-Design-Model-Card-Considerations.md#users--use-cases) + - [Technical limitations](0x24-Design-Model-Card-Considerations.md#technical-limitations) + - [Performance tradeoffs](0x24-Design-Model-Card-Considerations.md#performance-tradeoffs) + - [Fairness assessments](0x24-Design-Model-Card-Considerations.md#fairness-assessments) + - [Ethical considerations](0x24-Design-Model-Card-Considerations.md#ethical-considerations) + - [Environmental impact consideration](0x24-Design-Model-Card-Considerations.md#environmental-considerations) + +- [Additional model information](0x40-Design-Additional-Model-Information.md#additional-model-related-information) + - [Tokenizers and prompt templates](0x40-Design-Additional-Model-Information.md#tokenizers-and-prompt-templates) + - [Hardware, software & frameworks](0x40-Design-Additional-Model-Information.md#hardware-software--frameworks) + - [Training & testing details](0x40-Design-Additional-Model-Information.md#training--testing-details) + - [Intended use & ethics](0x40-Design-Additional-Model-Information.md#intended-use--ethics) #### Design notes diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index e5fc645..4851018 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -75,7 +75,7 @@ This example shows a list for what kind of technical limitations might be associ ..., "considerations": { "technicalLimitations": [ - "Greedy Decoding Degradation. The model is optimized for sampling-based generation. Using greedy decoding (temperature=0) can lead to performance degradation, repetitive loops, and "stuck" reasoning steps, particularly in the new Thinking Mode", + "Greedy Decoding Degradation. The model is optimized for sampling-based generation. Using greedy decoding (temperature=0) can lead to performance degradation, repetitive loops, and \"stuck\" reasoning steps, particularly in the new Thinking Mode", "Native Context Window Boundaries. While the model supports up to 131,072 tokens using YaRN scaling, its native pre-training context is limited to 32,768 tokens. Performance may degrade on very long sequences if proper scaling factors (like RoPE or YaRN) are not manually configured for local deployments.", "Synthetic Data \"Sanding\" Effects. Research indicates that Qwen3, like many models trained on massive synthetic datasets, can suffer from \"model collapse\" where rare edge cases or minority user behaviors are underrepresented, potentially leading to errors in complex, real-world production environments.", "Thinking Mode History Overhead. In multi-turn conversations, including the model's internal \"thinking\" steps in the chat history can confuse the model and consume unnecessary tokens. Best practices require developers to filter out \"thinking\" content from the history to maintain coherence." @@ -170,6 +170,22 @@ Based on technical reports and safety evaluations such as Qwen3Guard, the follow ### Fairness assessments +Fairness assessments convey information about the benefits and harms of the model to an identified at risk group. They involve measuring how models treat different social groups to ensure they do not perpetuate or amplify harmful social biases. + +For Large Language Models (LLMs), like Qwen, Mistral, or GPT, etc., assessments typically evaluate the model focusing on its training data, internal probabilities (weights and biases), and final generated text using metrics that can be statistically analyzed. + +Assessments consider evaluations at all stages of the model development lifecycle including: + +* **Data Bias Auditing** (Pre-processing): Analyzing training datasets for under-represented groups, improper labeling, or historical biases that could cause discriminatory outcomes. +* **Disaggregated Performance Metrics** (Measurement): Evaluating model performance (e.g., accuracy, false positives/negatives) across different demographic groups (e.g., race, gender) to identify, for example, higher error rates for certain populations. +* **Impact Assessments** (Contextual) - Assessing how AI systems affect specific groups of people, identifying potential harms to rights, safety, or livelihoods, which is a key requirement for high-risk AI under the EU AI Act. +* **Adversarial Testing** (Verification) - Intentionally challenging the AI model with edge cases to uncover hidden biases or vulnerabilities. +* **Algorithmic Fairness Interventions** (In-processing/Post-processing) - Implementing technical solutions to correct identified disparities, such as modifying the model architecture during training or adjusting output thresholds to ensure fair decision-making. + +###### Example: LLM fairness assessment + +This example shows how fairness assessment information would be included in a a CycloneDX `modelCard` object. + ```json "component": { "type": "machine-learning-model", @@ -178,12 +194,12 @@ Based on technical reports and safety evaluations such as Qwen3Guard, the follow "modelCard": { ..., "considerations": { + ..., "fairnessAssessments": [ { - "groupAtRisk": "", - "benefits": "", - "harms": "", - "mitigationStrategy": "" + "groupAtRisk": "People identified by characteristics such as race, gender, and disability status.", + "harms": "The model was found to produce discriminatory outcomes across protected characteristics, including race, gender, and disability status. For example, individuals categorized as \"gypsy\" or \"mute\" were incorrectly labeled as untrustworthy in task assignment scenarios.", + "mitigationStrategy": "Researchers recommend using Reinforcement Learning from Artificial Intelligence Feedback (RLAIF) and rule-based rewards to align the model with specific legal standards like the EU AI Act." }, { "groupAtRisk": "", @@ -198,6 +214,8 @@ Based on technical reports and safety evaluations such as Qwen3Guard, the follow } ``` + + --- ### Environmental considerations diff --git a/ML-BOM/en/0x40-Design-Other.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md similarity index 72% rename from ML-BOM/en/0x40-Design-Other.md rename to ML-BOM/en/0x40-Design-Additional-Model-Information.md index c0c1ed8..3327f49 100644 --- a/ML-BOM/en/0x40-Design-Other.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -1,6 +1,6 @@ # ML-BOM Design and Best Practices -## Other +## Additional model-related information This section describes the design and best practices when providing other model-related information an ML model's component and model card within a CycloneDX ML-BOM. @@ -11,6 +11,23 @@ For convenience, here are links to the specific sections for each of those infor - [Training & testing details]() - [Intended use & ethics]() +### Tokenizers and prompt templates + +TODO + +### Hardware, software & frameworks + +TODO + +### Training & testing details + +TODO + +### Intended use & ethics + +TODO + +
\newpage
diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index 82e0506..ebc9596 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -17,22 +17,31 @@ This appendix includes references to resources, standards, technologies and mode --- -#### Standards and regulatory references +#### Regulatory references and standards + +##### Regulatory references * [Ecma Technical Committee 54 - Software and System Transparency.](https://tc54.org) - Standardizing core data formats, APIs, and algorithms that advance software and system transparency. * [ECMA-424 BOM Specification](https://tc54.org/cyclonedx/) - The CycloneDX specification for describing software, hardware and data components, services, dependencies, composition, attestations, vulnerabilities, licenses, formulations and more. * [ECMA-427 PURL Specification](https://ecma-international.org/publications-and-standards/standards/ecma-427/) - This standard defines the Package-URL (PURL) syntax for identifying software packages independently from their ecosystem or distribution channel * [ECMA-428 Common Lifecycle Enumeration (CLE) specification](https://ecma-international.org/publications-and-standards/standards/ecma-428/) - The CLE provides a standardized format for communicating software component lifecycle events in a machine-readable format. * [European Union's Cyber Resilience Act (EU CRA)](https://www.european-cyber-resilience-act.com/) - * [Cyber Resilience Act (CRA) | The Final Text](https://www.european-cyber-resilience-act.com/Cyber_Resilience_Act_Articles.html) + * [Cyber Resilience Act (CRA)](https://www.european-cyber-resilience-act.com/Cyber_Resilience_Act_Articles.html) - "The Final Text" +* [EU’s AI Act](https://eur-lex.europa.eu/eli/reg/2024/1689/oj/eng) - The European Union's comprehensive legal framework for artificial intelligence, designed to ensure that AI systems used in the European Union are safe, ethical, and trustworthy. * [Article 53: Obligations for Providers of General-Purpose AI Models](https://artificialintelligenceact.eu/article/53/) * [Annex XI: Technical Documentation Referred to in Article 53(1), Point (a) – Technical Documentation for Providers of General-Purpose AI Models](https://artificialintelligenceact.eu/annex/11/) * [Explanatory Notice and Template for the Public Summary of Training Content for general-purpose AI models](https://digital-strategy.ec.europa.eu/en/library/explanatory-notice-and-template-public-summary-training-content-general-purpose-ai-models) + +##### Standards + * [Linux Foundation projects](https://www.linuxfoundation.org/projects) * [System Package Data Exchange™ (SPDX®)](https://spdx.dev/) * [SPDX License IDs](https://spdx.dev/ids/) * [SPDX License List](https://spdx.org/licenses/) * [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework) + * [NIST Artificial Intelligence Risk Management +Framework (AI RMF 1.0)](https://nvlpubs.nist.gov/nistpubs/ai/nist.ai.100-1.pdf) (PDF) - A flexible guide designed to help organizations manage AI-related risks and promote trustworthy AI development. + --- From 9f5b1425d4c5c401d664d29f75bd4934e9874066 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 29 Jan 2026 09:01:13 -0600 Subject: [PATCH 051/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...Design-Model-Card-Quantitative-Analysis.md | 71 ++++++++++--------- ML-BOM/en/0x90-Appendix-A_Glossary.md | 8 ++- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 6e523e6..91382aa 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -13,7 +13,9 @@ This section will feature guidance on filling out information in the Cyclone mod ### What is quantitative analysis -A quantitative analysis of an AI model involves using mathematical and statistical methods to objectively measure and evaluate its performance, behavior, and outputs using numerical data, focusing on how much or how often, unlike qualitative analysis which looks at why. It assesses metrics like accuracy, precision, recall, efficiency, and consistency, transforming raw data into verifiable insights to understand patterns, test hypotheses, and ensure reliability for decision-making, moving beyond subjective human interpretation. +Quantitative analysis is the process of using metrics on benchmarks to determine if a model is reliable, safe, or better than another. It involves comparing the metric results against the benchmark standard to assess performance, identify limitations, and track progress over time. + + #### The value of quantitative analysis @@ -22,56 +24,55 @@ A quantitative analysis of an AI model involves using mathematical and statistic * **Pattern & Trend Detection**: Identifies numerical patterns, correlations, and trends within large or complex datasets that might be missed manually. * **Testing Hypotheses**: Enables the statistical testing of assumptions about model behavior allowing for comparisons against similar models for given tasks. ---- +#### Benchmarks -### Performance metrics +Benchmarks (The "Where" & "How"): These are standardized test datasets, scenarios, or tasks (e.g., ImageNet, GLUE) that define the "playing field". They provide a consistent environment for evaluating different models. -Describes any standardized metrics and evaluations used to measure and compare the effectiveness, efficiency and output correctness of a model providing a crucial, objective way to determine which model is best suited for a particular task or deployment environment. +##### Types of machine learning benchmarks -> [!Note] Currently, CycloneDx supports declaring metrics in the area of *performance benchmarks* which is the most consistently seen set of named metrics described within model cards today. +ML model benchmarks use standardized datasets to objectively compare model quality, efficiency, fairness, and speed, providing a shared baseline for identifying areas for improvement in various categories. + +* [Natural Language Processing (NLP)](0x90-Appendix-A_Glossary.md#natural-language-processing-nlp) (e.g., speech recognition or text classification) or +* [Computer Vision](0x90-Appendix-A_Glossary.md#computer-vision) (e.g., digital image or video recognition). -#### Types of machine learning benchmarks + -• Task-Specific Benchmarks: Standardized datasets for common tasks (e.g., MNIST for digits, CIFAR-10 for images, IMDb for sentiment). -• System Benchmarks (MLPerf): Evaluate hardware (GPUs, TPUs) and software infrastructure for training and inference speed. -• Model-Specific Benchmarks: Assess different aspects of model quality, from basic metrics to advanced reasoning. [1, 3, 5, 6] +#### Metrics -Common Performance Metrics -• Classification: +> [!Note] Currently, CycloneDx supports declaring metrics in the area of *performance benchmarks* which is the most consistently seen set of named metrics described within model cards today. - • Accuracy: Overall correctness. - • Precision: Of predicted positives, how many are correct. - • Recall (Sensitivity): Of actual positives, how many are found. - • F1 Score: Harmonic mean of Precision and Recall. - • ROC AUC: Area under the Receiver Operating Characteristic curve. +##### Common Performance Metrics -• Large Language Models (LLMs): +* **Classification: + * **Accuracy: Overall correctness. + * **Precision: Of predicted positives, how many are correct. + * **Recall (Sensitivity): Of actual positives, how many are found. + * **F1 Score: Harmonic mean of Precision and Recall. + * **ROC AUC: Area under the Receiver Operating Characteristic curve. - • MMLU: Measures knowledge across many subjects. - • HellaSwag: Tests commonsense reasoning. - • TruthfulQA: Assesses truthfulness in responses. +* Large Language Models (LLMs): -• Efficiency: + * **MMLU: Measures knowledge across many subjects. + * **HellaSwag: Tests commonsense reasoning. + * **TruthfulQA: Assesses truthfulness in responses. - • Latency/Throughput: Speed of prediction (inference). - • Resource Utilization: Memory, CPU/GPU usage. [2, 3, 4, 5] +*•* Efficiency: -Why Benchmarking Matters + * **Latency/Throughput: Speed of prediction (inference). + * **Resource Utilization: Memory, CPU/GPU usage. [2, 3, 4, 5] -• Fair Comparison: Enables objective comparison between different algorithms and models. -• Drives Progress: Identifies state-of-the-art (SOTA) performance and pushes innovation. -• Reproducibility: Ensures results can be verified and replicated. -• Transparency: Helps communicate AI value to stakeholders. [1, 3, 7, 8, 9, 10] +--- Examples of Benchmarks & Datasets -• Computer Vision: ImageNet, CIFAR. -• NLP: GLUE, SuperGLUE, SQuAD, MMLU. -• Repositories: Kaggle, UCI Machine Learning Repository, OpenML, {Milvus](https://milvus.io/ai-quick-reference/what-are-benchmark-datasets-in-machine-learning-and-where-can-i-find-them) https://milvus.io/ai-quick-reference/what-are-benchmark-datasets-in-machine-learning-and-where-can-i-find-them), TensorFlow Datasets, TorchVision. [1, 4, 6, 11] +* **Computer Vision: ImageNet, CIFAR. +* **NLP: GLUE, SuperGLUE, SQuAD, MMLU. +* **Repositories: Kaggle, UCI Machine Learning Repository, OpenML, {Milvus](https://milvus.io/ai-quick-reference/what-are-benchmark-datasets-in-machine-learning-and-where-can-i-find-them) https://milvus.io/ai-quick-reference/what-are-benchmark-datasets-in-machine-learning-and-where-can-i-find-them), TensorFlow Datasets, TorchVision. [1, 4, 6, 11] AI responses may include mistakes. @@ -87,9 +88,11 @@ AI responses may include mistakes. [10] https://www.emergentmind.com/topics/benchmarking-machine-learning-algorithms [11] https://www.meegle.com/en_us/topics/ai-model-evaluation/ai-model-benchmarking +--- +### Performance metrics - +These are specific, quantitative measures used to evaluate a model's behavior, such as accuracy, precision, recall, perplexity, or inference speed. They provide the raw, numerical data for analysis. ```json "component": diff --git a/ML-BOM/en/0x90-Appendix-A_Glossary.md b/ML-BOM/en/0x90-Appendix-A_Glossary.md index c0106cd..ccd2c34 100644 --- a/ML-BOM/en/0x90-Appendix-A_Glossary.md +++ b/ML-BOM/en/0x90-Appendix-A_Glossary.md @@ -37,11 +37,17 @@ The transformer's neural network architecture takes input data converts it to nu --- +##### Computer Vision + +is an area of artificial intelligence (AI) that enables computers to interpret, analyze, and extract meaningful information from digital images, videos, and other visual inputs. Using techniques like deep learning and neural networks, these systems simulate human vision to identify objects, recognize patterns, and automate tasks in industries such as healthcare, autonomous driving, and security. [1] + +[1] [IBM - What is computer vision?](https://www.ibm.com/think/topics/computer-vision) + ##### Natural Language Processing (NLP) is the processing of natural language information by a computer. NLP is a subfield of computer science and is closely associated with artificial intelligence. NLP is also related to information retrieval, knowledge representation, computational linguistics, and linguistics more broadly. -Major processing tasks in an NLP system include: speech recognition, text classification, natural language understanding, and natural language generation. [1] +Major processing tasks in an NLP system include: speech recognition, text classification, natural language understanding (NLU), and natural language generation. [1] [1] [Wikipedia - Natural language processing](https://en.wikipedia.org/wiki/Natural_language_processing) From 7a5a4034a1a2aa1f9b9f59ee4aa08b0887d648b1 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 29 Jan 2026 16:51:31 -0600 Subject: [PATCH 052/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...Design-Model-Card-Quantitative-Analysis.md | 28 ++++++++----- ML-BOM/en/0x90-Appendix-A_Glossary.md | 39 ++++++++++++------- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 91382aa..5f359d2 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -26,23 +26,33 @@ Quantitative analysis is the process of using metrics on benchmarks to determine #### Benchmarks -Benchmarks (The "Where" & "How"): These are standardized test datasets, scenarios, or tasks (e.g., ImageNet, GLUE) that define the "playing field". They provide a consistent environment for evaluating different models. +Benchmarks are standardized test datasets, scenarios, or tasks that define the "playing field". They provide a consistent environment for evaluating different models and enable the comparison of their metrics across similar models. ##### Types of machine learning benchmarks -ML model benchmarks use standardized datasets to objectively compare model quality, efficiency, fairness, and speed, providing a shared baseline for identifying areas for improvement in various categories. +Benchmarks use standardized datasets to objectively compare model quality, efficiency, fairness, and speed, providing a shared baseline for identifying areas for improvement in various categories. -* [Natural Language Processing (NLP)](0x90-Appendix-A_Glossary.md#natural-language-processing-nlp) (e.g., speech recognition or text classification) or -* [Computer Vision](0x90-Appendix-A_Glossary.md#computer-vision) (e.g., digital image or video recognition). +* **[Large Language Models (LLM)](0x90-Appendix-A_Glossary.md#large-language-model-llm)** and **[Natural Language Processing (NLP)](0x90-Appendix-A_Glossary.md#natural-language-processing-nlp)** (e.g., speech recognition or text classification) - These benchmarks evaluate reasoning, knowledge, and generation capabilities. +
A few examples of datasets used to benchmark these models include: - + as well as some examples that target specific informational areas: + * [GSM8K](https://huggingface.co/datasets/openai/gsm8k) (OpenAI), [MATH-500](https://huggingface.co/datasets/HuggingFaceH4/MATH-500) (Hugging Face): Benchmarks specifically designed to evaluate mathematical reasoning. + * [HumanEval](https://huggingface.co/datasets/openai/openai_humaneval) (OpenAI), [MBPP](https://huggingface.co/datasets/Muennighoff/mbpp) (Mostly Basic Python Problems ): Benchmarks for evaluating code generation and programming capabilities. + [IMDB](https://www.kaggle.com/datasets/lakshmi25npathi/imdb-dataset-of-50k-movie-reviews): a large dataset of 50K, highly polarized, movie reviews for NLP sentiment analysis and classification. +
+* **[Computer Vision](0x90-Appendix-A_Glossary.md#computer-vision)** (e.g., digital image or video recognition) +These benchmarks measure the performance, accuracy, and efficiency of models in tasks like image classification, object detection, segmentation, and tracking.

Some example datasets: + + * [ImageNet](image-net.org): large-scale dataset for computer vision, featuring over 14 million annotated, high-resolution images across thousands of object categories organized by the [WordNet](https://en.wikipedia.org/wiki/WordNet) hierarchy. + * [MathVista](https://huggingface.co/datasets/AI4Math/MathVista): Used to evaluating math reasoning in Visual Contexts. It consists of three datasets, *IQTest*, *FunctionQA*, and *PaperQA*, which are tailored to evaluate visual reasoning on puzzle test figures, algebraic reasoning over functional plots, and scientific reasoning with academic paper figures, respectively. + * [MNIST](https://www.tensorflow.org/datasets/catalog/mnist) (Modified National Institute of Standards and Technology database) (link to the Tensorflow/Keras catalog): a large database of handwritten digits (glyphs) that is commonly used for training various image processing systems. -#### Metrics +#### Metrics > [!Note] Currently, CycloneDx supports declaring metrics in the area of *performance benchmarks* which is the most consistently seen set of named metrics described within model cards today. diff --git a/ML-BOM/en/0x90-Appendix-A_Glossary.md b/ML-BOM/en/0x90-Appendix-A_Glossary.md index ccd2c34..02e518d 100644 --- a/ML-BOM/en/0x90-Appendix-A_Glossary.md +++ b/ML-BOM/en/0x90-Appendix-A_Glossary.md @@ -1,16 +1,24 @@ # Appendix A: Glossary +### General machine learning terms + ##### Activation function An activation function is a mathematical operation applied to a neuron's output to introduce non-linearity, allowing the model to learn complex patterns beyond simple straight lines, essentially deciding if and how much a neuron "fires" based on its weighted inputs. [1] [1] [Activation functions in neural networks](https://www.youtube.com/watch?v=v1MhJs4A1i4&t=89s) -##### Quantization +##### Computer Vision -A technique to reduce the computational and memory costs of running inference by representing the ([tensor](#tensor)) weights and [activations](#activation-function) with low-precision data types like 8-bit integer (int8) instead of the usual 32-bit floating point (float32). [1] +is an area of artificial intelligence (AI) that enables computers to interpret, analyze, and extract meaningful information from digital images, videos, and other visual inputs. Using techniques like deep learning and neural networks, these systems simulate human vision to identify objects, recognize patterns, and automate tasks in industries such as healthcare, autonomous driving, and security. [1] -[1] [Hugging Face - Quantization](https://huggingface.co/docs/optimum/en/concept_guides/quantization#quantization) +[1] [IBM - What is computer vision?](https://www.ibm.com/think/topics/computer-vision) + +##### Large Language Model (LLM) + +A model trained with self-supervised machine learning on a vast amount of text, designed for [Natural Language Processing](#natural-language-processing-nlp) tasks, especially language generation. The largest and most capable LLMs are Generative Pre-trained [Transformers](#transformer) (GPTs) and provide the core capabilities of modern chatbots. LLMs can be fine-tuned for specific tasks or guided by prompt engineering. [1] + +[1] [Wikipedia - Large language model](https://en.wikipedia.org/wiki/Large_language_model) ##### Neural network @@ -18,14 +26,24 @@ A neural network consists of connected units or nodes called artificial neurons, [1] [Wikipedia - Neural network (machine_learning)](https://en.wikipedia.org/wiki/Neural_network_(machine_learning)) +##### Prompt engineering + +the process of structuring or crafting an instruction in order to produce better outputs from a generative artificial intelligence (AI) model. It typically involves designing clear queries, adding relevant context, and refining wording to guide the model toward more accurate, useful, and consistent responses/ [1] + +[1] [Wikipedia - prompt engineering]() + +##### Quantization + +A technique to reduce the computational and memory costs of running inference by representing the ([tensor](#tensor)) weights and [activations](#activation-function) with low-precision data types like 8-bit integer (int8) instead of the usual 32-bit floating point (float32). [1] + +[1] [Hugging Face - Quantization](https://huggingface.co/docs/optimum/en/concept_guides/quantization#quantization) + ##### Tensor In machine learning, the term tensor typically refers to data organized in a multidimensional array (M-way array), informally referred to as a "data tensor". Relational observations and concepts, established via ML model training of text, images, movies, sounds, and more can be stored in these "data tensors", and further analyzed either by artificial neural networks or tensor methods. [1] [1] [Wikipedia - Tensor (machine learning)](https://en.wikipedia.org/wiki/Tensor_(machine_learning)) ---- - ##### Transformer Transformers are a type of neural network architecture that transforms or changes an input sequence into an output sequence. They do this by learning context and tracking relationships between sequence components. [1] @@ -35,14 +53,6 @@ The transformer's neural network architecture takes input data converts it to nu [1] [AWS - What are transformers in artificial intelligence?](https://aws.amazon.com/what-is/transformers-in-artificial-intelligence/) [2] [Wikipedia - Transformer (deep learning)](https://en.wikipedia.org/wiki/Transformer_(deep_learning)) ---- - -##### Computer Vision - -is an area of artificial intelligence (AI) that enables computers to interpret, analyze, and extract meaningful information from digital images, videos, and other visual inputs. Using techniques like deep learning and neural networks, these systems simulate human vision to identify objects, recognize patterns, and automate tasks in industries such as healthcare, autonomous driving, and security. [1] - -[1] [IBM - What is computer vision?](https://www.ibm.com/think/topics/computer-vision) - ##### Natural Language Processing (NLP) is the processing of natural language information by a computer. NLP is a subfield of computer science and is closely associated with artificial intelligence. NLP is also related to information retrieval, knowledge representation, computational linguistics, and linguistics more broadly. @@ -51,10 +61,9 @@ Major processing tasks in an NLP system include: speech recognition, text classi [1] [Wikipedia - Natural language processing](https://en.wikipedia.org/wiki/Natural_language_processing) - --- -### Model formats +### Model format terms #### Huggingface Safetensors From 26d521cb5d0ac0d9677f59ac9c1647b84cf4dead Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 30 Jan 2026 11:17:32 -0600 Subject: [PATCH 053/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...Design-Model-Card-Quantitative-Analysis.md | 81 +++++++++---------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 5f359d2..3e1b23d 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -24,7 +24,9 @@ Quantitative analysis is the process of using metrics on benchmarks to determine * **Pattern & Trend Detection**: Identifies numerical patterns, correlations, and trends within large or complex datasets that might be missed manually. * **Testing Hypotheses**: Enables the statistical testing of assumptions about model behavior allowing for comparisons against similar models for given tasks. -#### Benchmarks +--- + +### Benchmarks Benchmarks are standardized test datasets, scenarios, or tasks that define the "playing field". They provide a consistent environment for evaluating different models and enable the comparison of their metrics across similar models. @@ -51,58 +53,32 @@ These benchmarks measure the performance, accuracy, and efficiency of models in * [MathVista](https://huggingface.co/datasets/AI4Math/MathVista): Used to evaluating math reasoning in Visual Contexts. It consists of three datasets, *IQTest*, *FunctionQA*, and *PaperQA*, which are tailored to evaluate visual reasoning on puzzle test figures, algebraic reasoning over functional plots, and scientific reasoning with academic paper figures, respectively. * [MNIST](https://www.tensorflow.org/datasets/catalog/mnist) (Modified National Institute of Standards and Technology database) (link to the Tensorflow/Keras catalog): a large database of handwritten digits (glyphs) that is commonly used for training various image processing systems. +--- -#### Metrics - -> [!Note] Currently, CycloneDx supports declaring metrics in the area of *performance benchmarks* which is the most consistently seen set of named metrics described within model cards today. - -##### Common Performance Metrics - -* **Classification: - * **Accuracy: Overall correctness. - * **Precision: Of predicted positives, how many are correct. - * **Recall (Sensitivity): Of actual positives, how many are found. - * **F1 Score: Harmonic mean of Precision and Recall. - * **ROC AUC: Area under the Receiver Operating Characteristic curve. - -* Large Language Models (LLMs): - - * **MMLU: Measures knowledge across many subjects. - * **HellaSwag: Tests commonsense reasoning. - * **TruthfulQA: Assesses truthfulness in responses. - -*•* Efficiency: +### Metrics - * **Latency/Throughput: Speed of prediction (inference). - * **Resource Utilization: Memory, CPU/GPU usage. [2, 3, 4, 5] +> [!Note] Currently, CycloneDx supports declaring metrics relative to *performance benchmarks* which is the most consistently documented metrics described within producer published model cards. --- -Examples of Benchmarks & Datasets - -* **Computer Vision: ImageNet, CIFAR. -* **NLP: GLUE, SuperGLUE, SQuAD, MMLU. -* **Repositories: Kaggle, UCI Machine Learning Repository, OpenML, {Milvus](https://milvus.io/ai-quick-reference/what-are-benchmark-datasets-in-machine-learning-and-where-can-i-find-them) https://milvus.io/ai-quick-reference/what-are-benchmark-datasets-in-machine-learning-and-where-can-i-find-them), TensorFlow Datasets, TorchVision. [1, 4, 6, 11] +### Performance metrics -AI responses may include mistakes. +Performance metrics are specific, quantitative measures used to evaluate a model's behavior, such as accuracy, precision, recall, perplexity, or inference speed. They provide the raw, numerical data for analysis. -[1] https://labelstud.io/learningcenter/what-are-benchmarks/ -[2] https://www.ibm.com/think/topics/model-performance -[3] https://mlcommons.org/benchmarks/ -[4] https://www.teqfocus.com/blog/benchmarking-large-language-models-a-comprehensive-guide/ -[5] https://coe-379l-sp24.readthedocs.io/en/latest/unit04/ml_benchmarks.html -[6] https://milvus.io/ai-quick-reference/what-are-benchmark-datasets-in-machine-learning-and-where-can-i-find-them -[7] https://www.tutorialspoint.com/what-are-the-machine-learning-benchmarks -[8] https://www.youtube.com/watch?v=_lmT4Nqtm-A -[9] https://help.pecan.ai/en/articles/7338218-understanding-pecan-s-benchmarks -[10] https://www.emergentmind.com/topics/benchmarking-machine-learning-algorithms -[11] https://www.meegle.com/en_us/topics/ai-model-evaluation/ai-model-benchmarking +##### Common Performance Metrics ---- +* **Accuracy** - Overall correctness. +* **Precision** - Of predicted positives, how many are correct. +* **Recall** (Sensitivity) - Of actual positives, how many are found. +* **F1 Score**: Harmonic mean of *Precision* and *Recall*. + + -### Performance metrics +###### Example: Declaring an MMLU accuracy result -These are specific, quantitative measures used to evaluate a model's behavior, such as accuracy, precision, recall, perplexity, or inference speed. They provide the raw, numerical data for analysis. +TODO ```json "component": @@ -129,13 +105,30 @@ These are specific, quantitative measures used to evaluate a model's behavior, s } } ``` + +###### Example: Declaring an F1 Score + +TODO + +```json +"quantitativeAnalysis": { + "performanceMetrics": [ + { + "type": "F1 Score", + "value": "0.87", + "slice": "Validation Set" + } + ] +} +``` + --- #### Graphics TODO -### Example: Graphis +### Example: Graphics ```json { From 42d53e337171f4606a948ec0e58541aaaa9e52ed Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 30 Jan 2026 15:11:41 -0600 Subject: [PATCH 054/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...Design-Model-Card-Quantitative-Analysis.md | 67 +++++++++++++------ ML-BOM/en/0x91-Appendix-B_References.md | 3 +- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 3e1b23d..98b09c5 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -37,14 +37,22 @@ Benchmarks use standardized datasets to objectively compare model quality, effic * **[Large Language Models (LLM)](0x90-Appendix-A_Glossary.md#large-language-model-llm)** and **[Natural Language Processing (NLP)](0x90-Appendix-A_Glossary.md#natural-language-processing-nlp)** (e.g., speech recognition or text classification) - These benchmarks evaluate reasoning, knowledge, and generation capabilities.
A few examples of datasets used to benchmark these models include: - * [HellaSwag](https://huggingface.co/datasets/Rowan/hellaswag) / [WinoGrande](https://huggingface.co/datasets/allenai/winogrande): Common sense reasoning and pronoun resolution tasks. - * [MMLU](https://huggingface.co/datasets/cais/mmlu), [MMLU-Pro](https://huggingface.co/datasets/TIGER-Lab/MMLU-Pro) (Massive Multitask Language Understanding): Tests knowledge across STEM, humanities, and social sciences. - * [GLUE](https://gluebenchmark.com/): benchmarking resources for training, evaluating, and analyzing natural language understanding systems - - as well as some examples that target specific informational areas: - * [GSM8K](https://huggingface.co/datasets/openai/gsm8k) (OpenAI), [MATH-500](https://huggingface.co/datasets/HuggingFaceH4/MATH-500) (Hugging Face): Benchmarks specifically designed to evaluate mathematical reasoning. - * [HumanEval](https://huggingface.co/datasets/openai/openai_humaneval) (OpenAI), [MBPP](https://huggingface.co/datasets/Muennighoff/mbpp) (Mostly Basic Python Problems ): Benchmarks for evaluating code generation and programming capabilities. - [IMDB](https://www.kaggle.com/datasets/lakshmi25npathi/imdb-dataset-of-50k-movie-reviews): a large dataset of 50K, highly polarized, movie reviews for NLP sentiment analysis and classification. + * *General Tasks* + * [MMLU](https://huggingface.co/datasets/cais/mmlu), [MMLU-Pro](https://huggingface.co/datasets/TIGER-Lab/MMLU-Pro) (Massive Multitask Language Understanding): Tests knowledge across STEM, humanities, and social sciences. + * [HellaSwag](https://huggingface.co/datasets/Rowan/hellaswag) / [WinoGrande](https://huggingface.co/datasets/allenai/winogrande): Common sense reasoning and pronoun resolution tasks. + * [GLUE](https://gluebenchmark.com/): benchmarking resources for training, evaluating, and analyzing natural language understanding systems. GLUE's dataset is available in Hugging Face Hub ([nyu-mll/glue](https://huggingface.co/datasets/nyu-mll/glue)) and supports multiple tasks that can be evaluated independently, for example: + * *ax* - evaluates sentence understanding through Natural Language Inference (NLI) problems. + * *cola* - The Corpus of Linguistic Acceptability consists of English acceptability judgments drawn from books and journal articles on linguistic theory. + * *mnli* - The Multi-Genre Natural Language Inference Corpus consists of sentence pairs with textual entailment annotations. Given a premise sentence and a hypothesis sentence, the task is to predict whether the premise entails the hypothesis. + * *Math/STEM tasks* + * [GSM8K](https://huggingface.co/datasets/openai/gsm8k) (OpenAII, Grade School Math 8K): a dataset of 8.5K high quality linguistically diverse grade school math word problems. + * [MATH-500](https://huggingface.co/datasets/HuggingFaceH4/MATH-500) (Hugging Face): Benchmarks specifically designed to evaluate mathematical reasoning. + * *Coding Tasks* + * [HumanEval](https://huggingface.co/datasets/openai/openai_humaneval) (OpenAI): used to evaluate the functional correctness of code generated LLMs. It consists of hand-crafted programming problems designed to test reasoning and code synthesis abilities. + * [MBPP](https://huggingface.co/datasets/Muennighoff/mbpp) (Mostly Basic Python Problems ): Benchmarks for evaluating code generation and programming capabilities. + * [CodeXGLUE](https://github.com/microsoft/CodeXGLUE/tree/main/Code-Code/code-refinement) (MicroSoft, Code Refinement): Used to evaluate a model's ability to remove (i.e., "fix") bugs from Java code (i.e., refine the code) with accuracy being reported as [BLEU](https://learn.microsoft.com/en-us/azure/ai-services/translator/custom-translator/concepts/bleu-score) scores. + * *Other Tasks* + * [IMDB](https://www.kaggle.com/datasets/lakshmi25npathi/imdb-dataset-of-50k-movie-reviews): a large dataset of 50K, highly polarized, movie reviews for NLP sentiment analysis and classification.
* **[Computer Vision](0x90-Appendix-A_Glossary.md#computer-vision)** (e.g., digital image or video recognition) These benchmarks measure the performance, accuracy, and efficiency of models in tasks like image classification, object detection, segmentation, and tracking.

Some example datasets: @@ -53,13 +61,15 @@ These benchmarks measure the performance, accuracy, and efficiency of models in * [MathVista](https://huggingface.co/datasets/AI4Math/MathVista): Used to evaluating math reasoning in Visual Contexts. It consists of three datasets, *IQTest*, *FunctionQA*, and *PaperQA*, which are tailored to evaluate visual reasoning on puzzle test figures, algebraic reasoning over functional plots, and scientific reasoning with academic paper figures, respectively. * [MNIST](https://www.tensorflow.org/datasets/catalog/mnist) (Modified National Institute of Standards and Technology database) (link to the Tensorflow/Keras catalog): a large database of handwritten digits (glyphs) that is commonly used for training various image processing systems. +Again, the list above contains just a small number of examples of benchmarking datasets that can be used to train and evaluate models. + --- ### Metrics -> [!Note] Currently, CycloneDx supports declaring metrics relative to *performance benchmarks* which is the most consistently documented metrics described within producer published model cards. +AI benchmarking metrics are standardized, quantitative measures used to evaluate and compare the performance, accuracy, efficiency, and reliability of artificial intelligence models against established, uniform tasks and datasets. They function as a gauge progress in capabilities like reasoning, coding, and language understanding to provide simple comparisons to similar models. ---- +> [!Note] Currently, CycloneDx supports declaring metrics relative to *performance benchmarks* which is the most consistently documented metrics described within producer published model cards. ### Performance metrics @@ -67,7 +77,7 @@ Performance metrics are specific, quantitative measures used to evaluate a model ##### Common Performance Metrics -* **Accuracy** - Overall correctness. +* **Accuracy** - Overall correctness; typically represented as a percentage of correct responses to the full set of problems posed by a benchmark's dataset. * **Precision** - Of predicted positives, how many are correct. * **Recall** (Sensitivity) - Of actual positives, how many are found. * **F1 Score**: Harmonic mean of *Precision* and *Recall*. @@ -76,9 +86,17 @@ Performance metrics are specific, quantitative measures used to evaluate a model * **Latency/Throughput: Speed of prediction (inference). * **Resource Utilization: Memory, CPU/GPU usage. --> -###### Example: Declaring an MMLU accuracy result +###### Example: Declaring the MMLU accuracy score for Qwen-7B -TODO +The Qwen3 accuracy scores, for various benchmarks, are published in their [QwenLM/Qwen](https://github.com/QwenLM/Qwen?tab=readme-ov-file#performance) GitHub repository's README. + +This appears as a table inclusive of all Qwen3 models along with other similar models for comparison. Here is the table row for all Qwen-7B benchmarks: + +| Model | MMLU | C-Eval | GSM8K | MATH | HumanEval | MBPP | BBH | CMMLU | +|:------------------|:--------:|:--------:|:--------:|:--------:|:---------:|:--------:|:--------:|:--------:| +| **Qwen-7B** | 58.2 | 63.5 | 51.7 | 11.6 | 29.9 | 31.6 | 45.0 | 62.2 | + +The MMLU score from the table would be declared as a performance metric as follows: ```json "component": @@ -91,13 +109,11 @@ TODO "quantitativeAnalysis": { "performanceMetrics": [ { - "type": "benchmark_score", - "value": "The value of the performance metric", - // "slice": "The name of the slice this metric was computed on. By default, assume this metric is not sliced", - "slice": "Specific benchmark name (e.g., MMLU, GSM8K)" + "type": "MMLU (5-shot)", + "value": "58.2", "confidenceInterval": { - "lowerBound": "The lower bound of the confidence interval", - "upperBound": "The upper bound of the confidence interval" + "lowerBound": "94.28", + "upperBound": "95.72" } } ] @@ -106,7 +122,12 @@ TODO } ``` -###### Example: Declaring an F1 Score +###### Field notes + +* **slice** - the `slice` property was omitted indicating the full dataset was used for performance benchmarking. +* **confidenceInterval** - the values provided reflect Statistical Confidence Interval (Accuracy) for the full MMLU test set (approx. 14,000–15,900 questions) which is 95% ±0.72. + +###### Example: Declaring a GLUE F1 Score TODO @@ -114,14 +135,16 @@ TODO "quantitativeAnalysis": { "performanceMetrics": [ { - "type": "F1 Score", + "type": "GLUE (F1 Score)", "value": "0.87", - "slice": "Validation Set" + "slice": "cola" } ] } ``` +* **slice** - the `slice` property references a named subset `cola` (Corpus of Linguistic Acceptability) which is a subset of the GLUE tests; "cola" consists of single-sentence task to determine if a sentence is grammatically correct or not. + --- #### Graphics diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index ebc9596..a940361 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -69,7 +69,8 @@ Huggingface model (repositories) typically support the `.safetensors` Huggingfac * [microsoft/resnet-50](https://huggingface.co/microsoft/resnet-50/blob/main/README.md) - single `model.safetensors`, `pytorch_model.bin` file. * [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) - multiple `*.safetensors` files with `model.safetensors.index.json` index. - * [ArXiv - Qwen3 Technical Report (summary)](https://arxiv.org/html/2505.09388.pdf) + * [ArXiv - Qwen3 Technical Report](https://arxiv.org/abs/2505.09388) + * [ArXiv - STEM: Efficient Relative Capability Evaluation of LLMs through Structured Transition Samples](https://arxiv.org/html/2508.12096v1) - Analysis of Qwen3 model performance. ##### Kaggle From 8158c8224d76b1cf03dd1162d8ddeca151640176 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 30 Jan 2026 17:38:24 -0600 Subject: [PATCH 055/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x10-Introduction.md | 6 +++--- ML-BOM/en/0x15-Core-Concepts.md | 4 ++-- ML-BOM/en/0x24-Design-Model-Card-Considerations.md | 6 ++---- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/ML-BOM/en/0x10-Introduction.md b/ML-BOM/en/0x10-Introduction.md index affa955..f2680f2 100644 --- a/ML-BOM/en/0x10-Introduction.md +++ b/ML-BOM/en/0x10-Introduction.md @@ -17,11 +17,11 @@ ML-BOMs address critical challenges in the machine learning supply chain: - **Security & Vulnerability Management**: Help identify security risks, such as malicious (open-source) models or vulnerable dependencies, before they are integrated into production applications. -- **Governance & Compliance**: Support alignment with emerging global AI regulations and standards, such as the [European Union's Cyber Resilience Act (EU CRA)](https://www.european-cyber-resilience-act.com/) and the [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework), by providing necessary documentation for audits. +- **Governance & Compliance**: Provide documentation for audits or formal informational requests based upon requirements from emerging global AI regulations such as the [European Union's Cyber Resilience Act (EU CRA)](https://www.european-cyber-resilience-act.com/), including specifics for AI models and systems from the complementary [EU AI Act](https://artificialintelligenceact.eu/), as well as for voluntary, guidance-focused frameworks such as the [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework). -- **Risk Mitigation**: Enable teams to track data lineage, helping to identify potential data quality issues, privacy risks, or biases that could affect the model's performance and fairness. +- **Risk Mitigation**: Enable teams to track data lineage, helping to identify and eliminate potential data quality issues, privacy risks, or unwanted biases that could affect the model's performance and fairness. -- **Reproducibility & Explainability**: Provide a detailed record of components and training processes such that developers are able to reproduce models (via training from data sets) and their benchmarks and further validate claims on their accuracy and adherence to ethical considerations. +- **Reproducibility & Explainability**: Show adherence to software development lifecycle best practices by providing a detailed record of components and training processes such that developers are able to reproduce models (via training from datasets) and their benchmarks in order to validate claims of model accuracy and adherence to ethical considerations.
\newpage diff --git a/ML-BOM/en/0x15-Core-Concepts.md b/ML-BOM/en/0x15-Core-Concepts.md index 7a8b104..ee7880a 100644 --- a/ML-BOM/en/0x15-Core-Concepts.md +++ b/ML-BOM/en/0x15-Core-Concepts.md @@ -6,7 +6,7 @@ An ML-BOM typically documents the identifying elements, architecture, components - **Model identifiers**: Identifying information such as the model's [Package URL (PURL)](https://tc54.org/purl/) (e.g., from Huggingface `pkg:huggingface/distilbert-base-uncased@043235d6088ecd3dd5fb5ca3592b6913fd51602`) or other domain-specific identifiers within other registries. -- **Model metadata**: Descriptive details such as the model's name, version, developer, purpose, use cases, architecture, (hyper)parameters and any additional identifying elements. +- **Model metadata**: Descriptive details such as the model's name, version, license, developer, purpose, use cases, architecture, (hyper)parameters and any additional identifying elements. - **Model architecture**: Description of the composition of the model's neural network including configurations, layers, input/output parameters, attention mechanisms, etc. used at network processing stages. @@ -19,7 +19,7 @@ This informational category may also include operational and application aspects - **Training & testing details**: Information about the computational environment and systems (software, hardware, operating system, and GPUs) used for training or evaluation along with necessary configurations, hyperparameters, and evaluation metrics. -- **Intended use & ethics**: Documentation of the model's intended use, known limitations, safety guardrails, and ethical considerations. +- **Intended use & ethical considerations**: Documentation of the model's intended use, known limitations, safety guardrails, and ethical considerations. - **Environmental impacts**: Documentation of the resource needed to train or execute the model which have an environmental impact or cost (e.g., data center energy and water cooling cost details). diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 4851018..c284239 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -6,13 +6,11 @@ This section will feature guidance on filling out information in the Cyclone model card's `considerations` object and its subcomponents including: -This section will feature guidance on filling out information in the Cyclone model card's `modelParameters` object and its subcomponents including: - * [Users](#users) - Who are the intended users of the model? -* [Use cases](#use-cases) - What are the intended use cases of the model? +* [Use cases](#use-cases) - What are the intended use cases for the model inclusive of the Operational Design Domains (ODD)? * [Technical limitations](#technical-limitations) - What are the known technical limitations of the model? For example, "What kind(s) of data should the model be expected not to perform well on?", "What are the factors that might degrade model performance?". * [Performance tradeoffs](#performance-tradeoffs) - What are the known tradeoffs in accuracy/performance of the model? -* [Ethical considerations]() - What are the ethical risks involved in the application of this model? +* [Ethical considerations](#ethical-considerations) - How to disclose known ethical risks involved in the application of this model? * [Fairness assessments](#fairness-assessments) - How does the model affect groups at risk of being systematically disadvantaged? What are the harms and benefits to the various affected groups? * [Environmental considerations](#environmental-considerations) - What are the various environmental impacts the corresponding machine learning model has exhibited across its lifecycle? From c4626c7790db12e8cec772612ca43045850662c1 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 2 Feb 2026 11:55:08 -0600 Subject: [PATCH 056/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- .../0x24-Design-Model-Card-Considerations.md | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index c284239..61cfdcd 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -62,7 +62,21 @@ This example shows a list for what kind of user and use case information would b ### Technical limitations -This example shows a list for what kind of technical limitations might be associated with a typical Large Language Model (LLM) that is multi-lingual and supports code/instruct capabilities with similar (i.e., ~`8B`) parameter size. +Since ML models are fundamentally probabilistic and operate on pattern recognition from the data they are trained on, they are prone to various technical limitations. + +Some of these limitations include: + +* **Hallucination & Inaccuracy**: Due to their autoregressive nature, models prioritize generating plausible-sounding text over factual accuracy (a.k.a. "sycophancy"). +* **Context Window Constraints**: Limited memory prevents the model from processing or remembering long, complex interactions or large documents at once. +* **Reasoning & Math Deficiencies**: They often struggle with complex, multi-step logic and mathematical reasoning. +* **Knowledge Cutoff**: Models are generally frozen in time, meaning they cannot access real-time information without external retrieval systems. +* **Opacity** (lack of traceable reasoning): models' complex architectures make it difficult to trace how a specific output was generated. +* **Probabilistic Output Inconsistency**: The same prompt can yield different results (e.g., using different seeds or system context carryover), causing reliability issues. +* **Bias Reinforcement**: Models often replicate or amplify biases present in their training data. This has become more problematic with greater reliance on synthetic training data. + +###### Example: Sample technical limitations for Qwen3-7B + +This example shows a list for what kind of technical limitations might be associated with a typical Large Language Model (LLM) that is multi-lingual and supports code/instruct capabilities with similar parameter size. ```json "component": { @@ -87,6 +101,20 @@ This example shows a list for what kind of technical limitations might be associ ### Performance Tradeoffs +When creating Machine Learning (ML) models, developers must navigate several core performance tradeoffs to align model capabilities with business needs and technical constraints. + +Some of these tradeoffs considerations include: + +* **Accuracy vs. Interpretability**: Complex models often provide higher accuracy but are "black boxes," making them hard to interpret. Simpler models are easy to explain but may not capture complex patterns, sacrificing performance for transparency. +* **Accuracy vs. Speed/Latency**: Highly accurate models often require significant computation, leading to slower inference times. In production, a slightly less accurate model that responds in milliseconds is frequently preferred over a highly accurate model that takes seconds. +* **Bias vs. Variance** (Generalization): Highly flexible models (low bias) can overfit to training data, leading to high variance and poor performance on new data. Conversely, simpler models (high bias) may underfit, missing patterns altogether. +* **Complexity vs. Resource Constraints** (Cost): Larger, more complex models require more data, training time, and computational power (GPUs/CPUs). Developers must balance the need for model performance against budget, infrastructure, and deployment constraints. +* **Precision vs. Recall**: For models that perform classification, developers often must choose whether to minimize false positives (high precision) or false negatives (high recall). + +###### Example: Performance tradeoffs for Qwen3-7B + +This example how to provide performance tradeoffs against a few that have been acknowledged for the Qwen3 &B parameter model. + ```json "component": { "type": "machine-learning-model", @@ -180,7 +208,7 @@ Assessments consider evaluations at all stages of the model development lifecycl * **Adversarial Testing** (Verification) - Intentionally challenging the AI model with edge cases to uncover hidden biases or vulnerabilities. * **Algorithmic Fairness Interventions** (In-processing/Post-processing) - Implementing technical solutions to correct identified disparities, such as modifying the model architecture during training or adjusting output thresholds to ensure fair decision-making. -###### Example: LLM fairness assessment +###### Example: LLM fairness assessment for Qwen3-7B This example shows how fairness assessment information would be included in a a CycloneDX `modelCard` object. @@ -258,9 +286,9 @@ The type of activity that is part of a machine learning model development or ope ##### CO2 cost offset -###### Example: - +###### Example: "Fake" llama3 environmental considerations +This example is for a "fake" model based upon the llama3 architecture. ```json { From e86b5ab81e81c05badf039183b4f63586144288b Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 2 Feb 2026 13:02:09 -0600 Subject: [PATCH 057/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- .../0x24-Design-Model-Card-Considerations.md | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 61cfdcd..9926a5f 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -261,30 +261,34 @@ Summary of EU AI Act Environmental Disclosure Rules for GPAI Models: > [!Note] Since most trained models are published under some form of open license, most providers do not currently disclose the costs of training their models. -##### Activity - -The type of activity that is part of a machine learning model development or operational lifecycle that has an associated energy consumption. - -| Value | Description | -|---|---| -| **design** | A model design including problem framing, goal definition and algorithm selection.| -| **data-collection** |Model data acquisition including search, selection and transfer.| -| **data-preparation** | Model data preparation including data cleaning, labeling and conversion. | -| **training** | Model building, training and generalized tuning. | -| **fine-tuning** | Refining a trained model to produce desired outputs for a given problem space. | -| **validation** | Model validation including model output evaluation and testing. | -| **deployment** | Explicit model deployment to a target hosting infrastructure. | -| **inference** | Generating an output response from a hosted model from a set of inputs. | -| **other** | A lifecycle activity type whose description does not match currently defined values. | - -##### Energy providers - -##### Activity energy cost - -##### CO2 cost equivalent - -##### CO2 cost offset - +Each "consumption" entry consists of the following which are explained in more detail below: + +* **Activity** - The type of activity that was part of the ML model development or operational lifecycle with an associated energy cost. + + | Value | Description | + |---|---| + | **design** | A model design including problem framing, goal definition and algorithm selection.| + | **data-collection** |Model data acquisition including search, selection and transfer.| + | **data-preparation** | Model data preparation including data cleaning, labeling and conversion. | + | **training** | Model building, training and generalized tuning. | + | **fine-tuning** | Refining a trained model to produce desired outputs for a given problem space. | + | **validation** | Model validation including model output evaluation and testing. | + | **deployment** | Explicit model deployment to a target hosting infrastructure. | + | **inference** | Generating an output response from a hosted model from a set of inputs. | + | **other** | A lifecycle activity type whose description does not match currently defined values. | + +* **Energy providers** - The provider(s) of the energy consumed by the associated model development lifecycle activity. This object is intended to fully describe the provider using the following fields: + * **description** - A description of the energy provider. + * **organization** - The organization that provides energy which may include its name, address, URL and contact information. + * **energySource** - A value that is one of coal, oil, natural-gas, nuclear, wind, solar, geothermal, hydropower, biofuel, unknown or other. + * **energyProvided** - The energy provided by the energy source for an associated activity using Kilowatt-hours (kWh). + * **externalReferences** - Optional references (links) to the energy provider. + +* **Activity energy cost** - The total energy cost associated with the model lifecycle activity using Kilowatt-hours (kWh). + +* **CO2 cost equivalent** - The CO2 cost (debit) equivalent to the total energy cost using tonnes of Carbon Dioxide (CO2) equivalent (tCO2eq). + +* **CO2 cost offset** - The CO2 offset (credit) for the CO2 equivalent cost using tonnes of Carbon Dioxide (CO2) equivalent (tCO2eq). ###### Example: "Fake" llama3 environmental considerations From a46d483af86940e0d1fe576127540970024be1cf Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 2 Feb 2026 14:15:10 -0600 Subject: [PATCH 058/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- .../en/0x22-Design-Model-Card-Parameters.md | 6 +- ...Design-Model-Card-Quantitative-Analysis.md | 2 +- ...x40-Design-Additional-Model-Information.md | 72 ++++++++++++++++--- 3 files changed, 65 insertions(+), 15 deletions(-) diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index 53e877c..a10bb43 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -299,9 +299,9 @@ The public datasets, as documented in the model's research paper include: Describes the input and output data types (formats) of the model. ->[!Note] The current object used to describe model inputs and outputs is limited to describing the data types strictly used for training and inference. Future revisions of CycloneDx plan to expand these objects to provide more detailed information especially in regard to names, formats and defaults for model configuration parameters and hyperparameters. +>[!Note] The current object used to describe model inputs and outputs is limited to describing the data types strictly used for training and inference. Future revisions of CycloneDX plan to expand these objects to provide more detailed information especially in regard to names, formats and defaults for model configuration parameters and hyperparameters. -In order to provide information on model parameters and hyperparameters using existing CycloneDx schema, it is recommended best practice as shown in the next section "[Declaring other properties](#declaring-other-properties)" and its "[Example: Model parameters & hyperparameters for the Qwen-7B model](#example-model-parameters--hyperparameters-for-the-qwen-7b-model)". +In order to provide information on model parameters and hyperparameters using existing CycloneDX schema, it is recommended best practice as shown in the next section "[Declaring other properties](#declaring-other-properties)" and its "[Example: Model parameters & hyperparameters for the Qwen-7B model](#example-model-parameters--hyperparameters-for-the-qwen-7b-model)". ```json { @@ -345,7 +345,7 @@ As shown in the [Qwen/Qwen-7B model repository files](0x20-Design-Model-Componen - [config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/config.json) - which contains configuration parameters (as key-value pairs) used for initializing the model's implementation. - [generation_config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/generation_config.json) - which contains model hyperparameters (as key-value pairs) and their suggested (default) values used for configuring the model for token generation (inference). -The JSON below shows how a few of the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model's parameters, as contained in the [config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/config.json) configuration file, would be declared within the CycloneDx `modelCard` object's `properties` array using the CycloneDx reserved namespace for AI/ML. +The JSON below shows how a few of the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model's parameters, as contained in the [config.json](https://huggingface.co/Qwen/Qwen-7B/blob/main/config.json) configuration file, would be declared within the CycloneDX `modelCard` object's `properties` array using the CycloneDX reserved namespace for AI/ML. ```json { diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 98b09c5..9241ff6 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -69,7 +69,7 @@ Again, the list above contains just a small number of examples of benchmarking d AI benchmarking metrics are standardized, quantitative measures used to evaluate and compare the performance, accuracy, efficiency, and reliability of artificial intelligence models against established, uniform tasks and datasets. They function as a gauge progress in capabilities like reasoning, coding, and language understanding to provide simple comparisons to similar models. -> [!Note] Currently, CycloneDx supports declaring metrics relative to *performance benchmarks* which is the most consistently documented metrics described within producer published model cards. +> [!Note] Currently, CycloneDX supports declaring metrics relative to *performance benchmarks* which is the most consistently documented metrics described within producer published model cards. ### Performance metrics diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 3327f49..7c78873 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -4,29 +4,79 @@ This section describes the design and best practices when providing other model-related information an ML model's component and model card within a CycloneDX ML-BOM. -For convenience, here are links to the specific sections for each of those informational areas: +Currently, the v1.7 CycloneDX specification does not have specific objects or fields to document these types of information directly. However, these sections will show how CycloneDX extension mechanisms such as `properties` and `externalReferences` can be used to provide and classify such additional ML-related information. -- [Tokenizers and prompt templates]() -- [Hardware, software & frameworks]() -- [Training & testing details]() -- [Intended use & ethics]() +For convenience, here are links to the specific sections for some of these acknowledged informational areas: + +- [Tokenizers and prompt templates](#tokenizers-and-prompt-templates) +- [Hardware, software & frameworks](#hardware-software--frameworks) +- [Training & testing details](#training--testing-details) ### Tokenizers and prompt templates -TODO +Tokenizers provide the preprocessing (encoding) and postprocessing (decoding) functions to convert input and output information to tokens that the associated ML model was trained on and used for inference. -### Hardware, software & frameworks +##### Tokenizers and templates as components -TODO +It is best practice to treat tokenizers and prompt templates as annotated components. -### Training & testing details +###### Example: Qwen3-7B tokenizer and template -TODO +Using the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model as published to Hugging Face, the tokenizer is published within the model repository and can be represented as components. This method extends the use of a CycloneDX "assembly" to declare the tokenizer as shown in the previous section "[Describing a model repository as a CycloneDX assembly](0x20-Design-Model-Component-Metadata.md#example-qwenqwen-7b-model-repository-files)". + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "metadata": + { + "component": + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", + ... + "components": [ + { + "type": "library", + "name": "tokenization_qwen.py", + "description": "Python tokenization classes for QWen (QWenTokenizer)", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@e7a368b#tokenization_qwen.py", + "purl": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#tokenization_qwen.py", + ..., + "properties": [ + { + "name": "cdx:ai-ml:model:tokenizer", + "value": "QWenTokenizer" + } + ] + }, + ... + ] + } + } + ... +} +``` + +###### Field notes + +* **properties** - Utilizes the reserved CycloneDX property name `cdx:ai-ml:model:tokenizer`, with a tokenizer class name, to annotate the component as being a "tokenizer". -### Intended use & ethics +--- + +### Including Manufacturing information for the ML model + +The following additional information, relative to the model, utilizes the CycloneDX objects for a Manufacturing Bill-of-Materials (or MBOM) to describe the frameworks, systems and platforms used to train or test the model. + +**Note**: This "manufacturing" information may be included within the ML-BOM itself or provided as a separate MBOM and cross-linked to each other using the CycloneDX `BOMLink` (see [BOM-Link](https://cyclonedx.org/capabilities/bomlink/) documentation). + +#### Hardware, software & frameworks TODO +#### Training & testing details + +TODO
\newpage From 7c64d27d3f15f333295e0e793f9b4155193e3e58 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 2 Feb 2026 14:54:38 -0600 Subject: [PATCH 059/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...Design-Model-Card-Quantitative-Analysis.md | 4 +-- .../0x24-Design-Model-Card-Considerations.md | 23 +++++++------- ...x40-Design-Additional-Model-Information.md | 31 +++++++++++++++++-- ML-BOM/en/0x85-Appendix-1-Examples.md | 2 +- ML-BOM/en/0x91-Appendix-B_References.md | 1 + 5 files changed, 45 insertions(+), 16 deletions(-) diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 9241ff6..247ae09 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -88,9 +88,9 @@ Performance metrics are specific, quantitative measures used to evaluate a model ###### Example: Declaring the MMLU accuracy score for Qwen-7B -The Qwen3 accuracy scores, for various benchmarks, are published in their [QwenLM/Qwen](https://github.com/QwenLM/Qwen?tab=readme-ov-file#performance) GitHub repository's README. +The Qwen accuracy scores, for various benchmarks, are published in their [QwenLM/Qwen](https://github.com/QwenLM/Qwen?tab=readme-ov-file#performance) GitHub repository's README. -This appears as a table inclusive of all Qwen3 models along with other similar models for comparison. Here is the table row for all Qwen-7B benchmarks: +This appears as a table inclusive of all Qwen models along with other similar models for comparison. Here is the table row for all Qwen-7B benchmarks: | Model | MMLU | C-Eval | GSM8K | MATH | HumanEval | MBPP | BBH | CMMLU | |:------------------|:--------:|:--------:|:--------:|:--------:|:---------:|:--------:|:--------:|:--------:| diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 9926a5f..74ac74e 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -20,7 +20,7 @@ This section will feature guidance on filling out information in the Cyclone mod Used to provide list describing the intended users of the model along with a list of envisioned use cases for the model. -###### Example: Qwen3/Qwen-7B +###### Example: Qwen/Qwen-7B This example shows a list for what kind of user and use case information would be expected for a typical `7B` parameter size Large Language Model (LLM) that is multi-lingual and supports code/instruct capabilities. @@ -42,12 +42,13 @@ This example shows a list for what kind of user and use case information would b "Local AI Enthusiast / Privacy-First User" ], "useCases": [ - "Utilizing the Qwen3-Coder variant within an IDE for real-time code completion, bug fixing, and unit test generation, benefiting from its \"Agentic\" capabilities for repository-scale understanding.", + "Utilizing the Qwen \"instruct\" variants within an IDE for real-time code completion, bug fixing, and unit test generation, benefiting from its \"Agentic\" capabilities for repository-scale understanding.", "Translating business, education or other content or informational materials to other languages and dialects while maintaining the original tone and cultural nuances.", "Deploying low-latency chatbots for high-volume inquiries where the 7B model acts as a \"triage\" agent, answering common questions and only escalating complex logic to other support mechanisms.", "Summarizing long-form research papers and generating initial drafts for school projects, utilizing the model's 128K context window to ingest entire PDFs at once.", "Implementing the model on specialized hardware for real-time visual perception and \"Thinking Mode\" reasoning to help an intelligent device navigate and interact with its environment based on natural language commands", - "Running a self-hosted instance to analyze internal security logs for anomalies, ensuring that sensitive infrastructure data never leaves the organization's firewall.", "Running a personal assistant locally on a laptop to answer questions or process private information such as emails or calendars without sending data to an external server." + "Running a self-hosted instance to analyze internal security logs for anomalies, ensuring that sensitive infrastructure data never leaves the organization's firewall.", + "Running a personal assistant locally on a laptop to answer questions or process private information such as emails or calendars without sending data to an external server." ], } } @@ -74,7 +75,7 @@ Some of these limitations include: * **Probabilistic Output Inconsistency**: The same prompt can yield different results (e.g., using different seeds or system context carryover), causing reliability issues. * **Bias Reinforcement**: Models often replicate or amplify biases present in their training data. This has become more problematic with greater reliance on synthetic training data. -###### Example: Sample technical limitations for Qwen3-7B +###### Example: Sample technical limitations for Qwen-7B This example shows a list for what kind of technical limitations might be associated with a typical Large Language Model (LLM) that is multi-lingual and supports code/instruct capabilities with similar parameter size. @@ -89,7 +90,7 @@ This example shows a list for what kind of technical limitations might be associ "technicalLimitations": [ "Greedy Decoding Degradation. The model is optimized for sampling-based generation. Using greedy decoding (temperature=0) can lead to performance degradation, repetitive loops, and \"stuck\" reasoning steps, particularly in the new Thinking Mode", "Native Context Window Boundaries. While the model supports up to 131,072 tokens using YaRN scaling, its native pre-training context is limited to 32,768 tokens. Performance may degrade on very long sequences if proper scaling factors (like RoPE or YaRN) are not manually configured for local deployments.", - "Synthetic Data \"Sanding\" Effects. Research indicates that Qwen3, like many models trained on massive synthetic datasets, can suffer from \"model collapse\" where rare edge cases or minority user behaviors are underrepresented, potentially leading to errors in complex, real-world production environments.", + "Synthetic Data \"Sanding\" Effects. Research indicates that Qwen, like many models trained on massive synthetic datasets, can suffer from \"model collapse\" where rare edge cases or minority user behaviors are underrepresented, potentially leading to errors in complex, real-world production environments.", "Thinking Mode History Overhead. In multi-turn conversations, including the model's internal \"thinking\" steps in the chat history can confuse the model and consume unnecessary tokens. Best practices require developers to filter out \"thinking\" content from the history to maintain coherence." ] } @@ -111,7 +112,7 @@ Some of these tradeoffs considerations include: * **Complexity vs. Resource Constraints** (Cost): Larger, more complex models require more data, training time, and computational power (GPUs/CPUs). Developers must balance the need for model performance against budget, infrastructure, and deployment constraints. * **Precision vs. Recall**: For models that perform classification, developers often must choose whether to minimize false positives (high precision) or false negatives (high recall). -###### Example: Performance tradeoffs for Qwen3-7B +###### Example: Performance tradeoffs for Qwen-7B This example how to provide performance tradeoffs against a few that have been acknowledged for the Qwen3 &B parameter model. @@ -125,8 +126,8 @@ This example how to provide performance tradeoffs against a few that have been a "considerations": { "performanceTradeoffs": [ "Intelligence Plateau in Domain-Specific Tasks. Research indicates that for specialized fields like legal text analysis, performance often flattens beyond the 7B parameter mark. While efficient, the 7B model may not offer the incremental reasoning gains found in the 32B or 235B models for complex, high-stakes domain reasoning.", - "Enhanced Quantization Sensitivity. The Qwen3-7B employs advanced pre-training techniques that reduce parameter redundancy. A documented tradeoff of this efficiency is a higher sensitivity to low-bit quantization (3-bit and below), where it exhibits more pronounced performance degradation compared to previous 7B generations.", - "Context Window Consistency. While the 7B model supports a native context window of 32,768 tokens, its performance degrades significantly more than the Qwen3-8B (which uses YaRN scaling to reach 128K+) when handling massive document sets. Users must tradeoff deep long-document comprehension for the 7B's lower memory footprint.", + "Enhanced Quantization Sensitivity. The Qwen-7B employs advanced pre-training techniques that reduce parameter redundancy. A documented tradeoff of this efficiency is a higher sensitivity to low-bit quantization (3-bit and below), where it exhibits more pronounced performance degradation compared to previous 7B generations.", + "Context Window Consistency. While the 7B model supports a native context window of 32,768 tokens, its performance degrades significantly more than the Qwen-8B (which uses YaRN scaling to reach 128K+) when handling massive document sets. Users must tradeoff deep long-document comprehension for the 7B's lower memory footprint.", "Conciseness vs. Contextual Nuance. Experiments show that the older 7B design prioritizes cleaner, easier-to-read, and more concise outputs. The tradeoff is a loss of the \"faithful and nuanced\" insights and richer context provided by the newer 8B and larger architectures.", "Agentic Capability Limitations. The 7B model shows a documented gap in its ability to follow complex multi-step instructions or navigate large software repositories, requiring tighter chunking and more finely tuned prompts to be effective", "Hardware Efficiency vs. Throughput. Running the 7B model on older hardware (e.g., 8GB VRAM cards) is possible but results in a tradeoff of throughput. Modern inference techniques like continuous batching and PagedAttention are less effective at this scale than on the larger, more parallelizable MoE models.", @@ -148,7 +149,7 @@ Used to provide list describing known ethical considerations when using a model. > [!Note] Since there is no agreed-upon standard for ethical considerations we recommend using the `name` field to additionally provide further description to clarify the name as needed. -###### Example: Qwen3-7B ethical considerations +###### Example: Qwen-7B ethical considerations Based on technical reports and safety evaluations such as Qwen3Guard, the following ethical considerations and mitigations are documented and typical of a multi-lingual LLM of similar parameter size and with a dense architecture: @@ -162,7 +163,7 @@ Based on technical reports and safety evaluations such as Qwen3Guard, the follow "considerations": { "ethicalConsiderations": [ { - "name": "Algorithmic and Cultural Bias. As a model trained on 36 trillion tokens across 119 languages, Qwen3-7B may still reflect societal biases, stereotypes, or representational harms present in its training data.", + "name": "Algorithmic and Cultural Bias. As a model trained on 36 trillion tokens across 119 languages, Qwen-7B may still reflect societal biases, stereotypes, or representational harms present in its training data.", "mitigationStrategy": "Use the Qwen-Gender framework or Chain-of-Thought (CoT) prompting to detect and reduce implicit biases in generated text." }, { @@ -208,7 +209,7 @@ Assessments consider evaluations at all stages of the model development lifecycl * **Adversarial Testing** (Verification) - Intentionally challenging the AI model with edge cases to uncover hidden biases or vulnerabilities. * **Algorithmic Fairness Interventions** (In-processing/Post-processing) - Implementing technical solutions to correct identified disparities, such as modifying the model architecture during training or adjusting output thresholds to ensure fair decision-making. -###### Example: LLM fairness assessment for Qwen3-7B +###### Example: LLM fairness assessment for Qwen-7B This example shows how fairness assessment information would be included in a a CycloneDX `modelCard` object. diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 7c78873..eeefc38 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -18,9 +18,9 @@ Tokenizers provide the preprocessing (encoding) and postprocessing (decoding) fu ##### Tokenizers and templates as components -It is best practice to treat tokenizers and prompt templates as annotated components. +It is best practice to treat tokenizers and prompt (or chat) templates as annotated components. -###### Example: Qwen3-7B tokenizer and template +###### Example: Declaring and annotating the Qwen-7B model's tokenizer Using the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model as published to Hugging Face, the tokenizer is published within the model repository and can be represented as components. This method extends the use of a CycloneDX "assembly" to declare the tokenizer as shown in the previous section "[Describing a model repository as a CycloneDX assembly](0x20-Design-Model-Component-Metadata.md#example-qwenqwen-7b-model-repository-files)". @@ -62,6 +62,33 @@ Using the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model as published * **properties** - Utilizes the reserved CycloneDX property name `cdx:ai-ml:model:tokenizer`, with a tokenizer class name, to annotate the component as being a "tokenizer". +###### Example: Annotating a model with its chat template + +For the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model, the chat template uses the standard [`ChatML`](https://huggingface.co/learn/llm-course/en/chapter11/2#common-template-formats) format (see [Hugging Face "Common Template Formats"](https://huggingface.co/learn/llm-course/en/chapter11/2#common-template-formats)) which can be referenced on the model component as follows: + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ... + "metadata": + { + "component": + { + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", + ..., + "properties": [ + { + "name": "cdx:ai-ml:model:template:chat", + "value": "ChatML" + } + ] + } + } + ... +} +``` + --- ### Including Manufacturing information for the ML model diff --git a/ML-BOM/en/0x85-Appendix-1-Examples.md b/ML-BOM/en/0x85-Appendix-1-Examples.md index 5c73759..6b6508c 100644 --- a/ML-BOM/en/0x85-Appendix-1-Examples.md +++ b/ML-BOM/en/0x85-Appendix-1-Examples.md @@ -2,7 +2,7 @@ ## Qwen/Qwen-7B ML-BOM -Throughout this guide provided incremental examples were shown of how to fill out various parts of an ML-BOM using the [Qwen3-7B](https://huggingface.co/Qwen/Qwen-7B) model. This section brings those together to show what a complete ML-BOM would look like for that model. +Throughout this guide provided incremental examples were shown of how to fill out various parts of an ML-BOM using the [Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model. This section brings those together to show what a complete ML-BOM would look like for that model. ```json { diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index a940361..88661b0 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -71,6 +71,7 @@ Huggingface model (repositories) typically support the `.safetensors` Huggingfac * [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) - multiple `*.safetensors` files with `model.safetensors.index.json` index. * [ArXiv - Qwen3 Technical Report](https://arxiv.org/abs/2505.09388) * [ArXiv - STEM: Efficient Relative Capability Evaluation of LLMs through Structured Transition Samples](https://arxiv.org/html/2508.12096v1) - Analysis of Qwen3 model performance. + * [Qwen/Qwen3-8B-GGUF](https://huggingface.co/Qwen/Qwen3-8B-GGUF) - Contains GGUF format (i.e., `.gguf` files) which contain quantized versions of the Qwen3 large language model which contains both dense and mixture-of-experts (MoE) architecture models. ##### Kaggle From 05a6639d694040695877546528919e9400c3497a Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 2 Feb 2026 14:55:09 -0600 Subject: [PATCH 060/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x91-Appendix-B_References.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index 88661b0..4cac91a 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -69,9 +69,9 @@ Huggingface model (repositories) typically support the `.safetensors` Huggingfac * [microsoft/resnet-50](https://huggingface.co/microsoft/resnet-50/blob/main/README.md) - single `model.safetensors`, `pytorch_model.bin` file. * [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) - multiple `*.safetensors` files with `model.safetensors.index.json` index. - * [ArXiv - Qwen3 Technical Report](https://arxiv.org/abs/2505.09388) * [ArXiv - STEM: Efficient Relative Capability Evaluation of LLMs through Structured Transition Samples](https://arxiv.org/html/2508.12096v1) - Analysis of Qwen3 model performance. * [Qwen/Qwen3-8B-GGUF](https://huggingface.co/Qwen/Qwen3-8B-GGUF) - Contains GGUF format (i.e., `.gguf` files) which contain quantized versions of the Qwen3 large language model which contains both dense and mixture-of-experts (MoE) architecture models. + * [ArXiv - Qwen3 Technical Report](https://arxiv.org/abs/2505.09388) ##### Kaggle From c30c83856437552cdd975f90dbb494f9af69c0e5 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 2 Feb 2026 14:57:20 -0600 Subject: [PATCH 061/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x40-Design-Additional-Model-Information.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index eeefc38..6ccf44a 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -101,9 +101,18 @@ The following additional information, relative to the model, utilizes the Cyclon TODO +```json + + +``` + #### Training & testing details -TODO +Ideally, the training and/or testing (evaluation) processes for a published model would be represented as workflows in a manufacturing BOM for the model and linked to its ML-BOM. + +```json + +```
\newpage From c421d11601e51d0b1ab66c91f2d0fd57d8b1c958 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 2 Feb 2026 15:50:43 -0600 Subject: [PATCH 062/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...x40-Design-Additional-Model-Information.md | 103 +++++++++++++++++- 1 file changed, 101 insertions(+), 2 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 6ccf44a..91d4843 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -99,21 +99,120 @@ The following additional information, relative to the model, utilizes the Cyclon #### Hardware, software & frameworks -TODO +This example shows a generalized example of how objects from the CycloneDX "Manufacturing" BOM (MBOM) would be used to declare the hardware and software stack used to run inference on a model. ```json - ``` #### Training & testing details Ideally, the training and/or testing (evaluation) processes for a published model would be represented as workflows in a manufacturing BOM for the model and linked to its ML-BOM. + +###### Example: Sample methodology for declaring training "stack" + +This example shows a generalized example of how objects from the CycloneDX "Manufacturing" BOM (MBOM) would be used to declare the hardware and software stack used to train a model. + +First you would declare all the "components" used for training as part of the `formulation` object: + +```json +", + "bomFormat": "CycloneDX", + "specVersion": "1.7", + ..., + "metadata": { + "component": { + "type": "container", + "name": "h100-training-image", + "version": "23.10-py3", + "purl": "pkg:oci/pytorch@sha256:456...789?repository_url=nvcr.io/nvidia/pytorch" + } + }, + ..., + "formulation": { + ..., + "components": [ + { + "type": "container", + "name": "h100-training-image", + "version": "23.10-py3", + "purl": "pkg:oci/pytorch@sha256:456...789?repository_url=nvcr.io/nvidia/pytorch" + }, + { + "type": "library", + "name": "nvidia-cuda-runtime", + "version": "12.2.0", + "purl": "pkg:generic/nvidia-cuda-runtime@12.2.0" + }, + { + "type": "library", + "name": "pytorch", + "version": "2.10.0", + "purl": "pkg:pypi/pytorch@2.10.0" + }, + { + "type": "library", + "name": "cuda-toolkit", + "version": "13.1.1", + "purl": "pkg:pypi/cuda-toolkit@13.1.1" + }, + { + "type": "library", + "name": "nccl", + "version": "2.19.3", + "purl": "pkg:generic/nccl@2.29.2" + }, + { + "type": "device", + "name": "NVIDIA H100 Tensor Core GPU", + "model": "H100 PCIe" + "description": "NVIDIA H100 Tensor Core GPU PCIe Device", + }, + ... + ] + }, + ... +} +``` + +Then you would describe the component "stack" as `runtimeTopology` dependencies: + ```json +"formulation": { + "workflow": { + "runtimeTopology": [ + { + "ref": "", + "dependsOn": "" + } + ] + } +``` + +The topology used for training would then be referenced on the training "task": +```json +"formulation": { + "workflow": { + "tasks": [ + { + "name": "Train model on dataset X", + "description": "Contains the detailed steps used to train the model on the referenced components (resources)." + "resourceReferences": [ ... ], + "steps": [ ... ], + "inputs": [ ... ], + "outputs": [ ... ], + ... + } + ] + } ``` +###### Field notes + +* **components** - The components listed to "train" the model shown above would also include "data" type components as described in the previous section "[Declaring datasets](0x22-Design-Model-Card-Parameters.md#declaring-datasets)". +
\newpage
From 4b3be353e2923e8463c78504d6d89ac8c4e6d9d6 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 2 Feb 2026 16:22:45 -0600 Subject: [PATCH 063/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...x40-Design-Additional-Model-Information.md | 52 +++++++++++-------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 91d4843..65c000c 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -123,10 +123,8 @@ First you would declare all the "components" used for training as part of the `f ..., "metadata": { "component": { - "type": "container", - "name": "h100-training-image", - "version": "23.10-py3", - "purl": "pkg:oci/pytorch@sha256:456...789?repository_url=nvcr.io/nvidia/pytorch" + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/fake.ai/llama3@abcd", } }, ..., @@ -136,31 +134,36 @@ First you would declare all the "components" used for training as part of the `f { "type": "container", "name": "h100-training-image", - "version": "23.10-py3", - "purl": "pkg:oci/pytorch@sha256:456...789?repository_url=nvcr.io/nvidia/pytorch" + "version": "25.03-py3-igpu", + "bom-ref": "pkg:oci/nvidia-pytorch@sha256:f398a0", + "purl": "pkg:oci/nvidia-pytorch@sha256:f398a0955ec5fcf9e3bbf77610225ff4e953e137423ab248e2bf32cd4971a1dc?repository_url=nvcr.io/nvidia/pytorch&tag=25.03-py3-igpu" }, { "type": "library", "name": "nvidia-cuda-runtime", "version": "12.2.0", + "bom-ref": "pkg:generic/nvidia-cuda-runtime@12.2.0", "purl": "pkg:generic/nvidia-cuda-runtime@12.2.0" }, { "type": "library", "name": "pytorch", "version": "2.10.0", + "bom-ref": "pkg:pypi/pytorch@2.10.0", "purl": "pkg:pypi/pytorch@2.10.0" }, { "type": "library", "name": "cuda-toolkit", "version": "13.1.1", + "bom-ref": "pkg:pypi/cuda-toolkit@13.1.1", "purl": "pkg:pypi/cuda-toolkit@13.1.1" }, { "type": "library", "name": "nccl", "version": "2.19.3", + "bom-ref": "pkg:generic/nccl@2.29.2", "purl": "pkg:generic/nccl@2.29.2" }, { @@ -168,6 +171,7 @@ First you would declare all the "components" used for training as part of the `f "name": "NVIDIA H100 Tensor Core GPU", "model": "H100 PCIe" "description": "NVIDIA H100 Tensor Core GPU PCIe Device", + "bom-ref": "nvidia-h100-pcie-gpu-1", }, ... ] @@ -176,21 +180,11 @@ First you would declare all the "components" used for training as part of the `f } ``` -Then you would describe the component "stack" as `runtimeTopology` dependencies: +###### Field notes -```json -"formulation": { - "workflow": { - "runtimeTopology": [ - { - "ref": "", - "dependsOn": "" - } - ] - } -``` +* **components** - The components listed to "train" the model shown above would also include "data" type components as described in the previous section "[Declaring datasets](0x22-Design-Model-Card-Parameters.md#declaring-datasets)". -The topology used for training would then be referenced on the training "task": +Then the training process would be represented as a CycloneDX `workflow` object with the details of the training tasks as `task` objects (inclusive of all relevant inputs, outputs, steps, etc.): ```json "formulation": { @@ -209,9 +203,25 @@ The topology used for training would then be referenced on the training "task": } ``` -###### Field notes +Lastly, you would describe the component "stack" as a graph of `runtimeTopology` dependencies. In this case, the training was done using an OCI (Open Container Initiative) standard container image which "provide" a declared set of component libraries (pre-installed on the image): -* **components** - The components listed to "train" the model shown above would also include "data" type components as described in the previous section "[Declaring datasets](0x22-Design-Model-Card-Parameters.md#declaring-datasets)". +```json +"formulation": { + "workflow": { + "runtimeTopology": [ + { + "ref": "pkg:oci/nvidia-pytorch@sha256:f398a0", + "dependsOn": "nvidia-h100-pcie-gpu-1", + "provides": [ + "cuda-toolkit", + "pkg:oci/nvidia-pytorch@sha256:f398a0", + "pkg:pypi/pytorch@2.10.0", + "pkg:generic/nccl@2.29.2" + ] + } + ] + } +```
\newpage From b5f0afda66b7a1fd01fce4a3eb619afdb3a89395 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 2 Feb 2026 17:18:44 -0600 Subject: [PATCH 064/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x40-Design-Additional-Model-Information.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 65c000c..343227e 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -99,13 +99,9 @@ The following additional information, relative to the model, utilizes the Cyclon #### Hardware, software & frameworks -This example shows a generalized example of how objects from the CycloneDX "Manufacturing" BOM (MBOM) would be used to declare the hardware and software stack used to run inference on a model. +This section describes a generalized example of how objects from the CycloneDX "Manufacturing" BOM (MBOM) would be used to declare the hardware and software stack used to run inference on a model. -```json - -``` - -#### Training & testing details +#### Providing training workflow details Ideally, the training and/or testing (evaluation) processes for a published model would be represented as workflows in a manufacturing BOM for the model and linked to its ML-BOM. From 16ed24a88f4d68eaaa930a36cd6398a72e4d96c1 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 2 Feb 2026 17:49:07 -0600 Subject: [PATCH 065/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...x40-Design-Additional-Model-Information.md | 89 +++++++++++-------- 1 file changed, 52 insertions(+), 37 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 343227e..0cf8763 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -93,24 +93,17 @@ For the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model, the chat temp ### Including Manufacturing information for the ML model -The following additional information, relative to the model, utilizes the CycloneDX objects for a Manufacturing Bill-of-Materials (or MBOM) to describe the frameworks, systems and platforms used to train or test the model. +This section shows how "manufacturing" (i.e., "training") information is provided relative to the model described by an ML-BOM. -**Note**: This "manufacturing" information may be included within the ML-BOM itself or provided as a separate MBOM and cross-linked to each other using the CycloneDX `BOMLink` (see [BOM-Link](https://cyclonedx.org/capabilities/bomlink/) documentation). +In short, this is accomplished utilizing objects which are part of the [CycloneDX Manufacturing Bill-of-Materials (or MBOM)](https://cyclonedx.org/capabilities/mbom/) to describe the frameworks, systems, platforms and libraries used to train the model against a detailed workflow-task description. -#### Hardware, software & frameworks +**Note**: The "manufacturing" information may be included within the ML-BOM itself or provided as a separate MBOM and cross-linked to each other using the CycloneDX `BOMLink` (see [BOM-Link](https://cyclonedx.org/capabilities/bomlink/) documentation). -This section describes a generalized example of how objects from the CycloneDX "Manufacturing" BOM (MBOM) would be used to declare the hardware and software stack used to run inference on a model. - -#### Providing training workflow details - -Ideally, the training and/or testing (evaluation) processes for a published model would be represented as workflows in a manufacturing BOM for the model and linked to its ML-BOM. +#### Declaring hardware & software training components +###### Example: Sample methodology for declaring the "training stack" -###### Example: Sample methodology for declaring training "stack" - -This example shows a generalized example of how objects from the CycloneDX "Manufacturing" BOM (MBOM) would be used to declare the hardware and software stack used to train a model. - -First you would declare all the "components" used for training as part of the `formulation` object: +First, create entries for all the "components" used in the training process as part of the `formulation` object: ```json ", @@ -180,45 +173,67 @@ First you would declare all the "components" used for training as part of the `f * **components** - The components listed to "train" the model shown above would also include "data" type components as described in the previous section "[Declaring datasets](0x22-Design-Model-Card-Parameters.md#declaring-datasets)". -Then the training process would be represented as a CycloneDX `workflow` object with the details of the training tasks as `task` objects (inclusive of all relevant inputs, outputs, steps, etc.): + +#### Providing training workflow details + +After the hardware and software "stack" of training components have been declared under the `formulation` object, a CycloneDX `workflow` object, with the details of the training tasks as `task` objects (inclusive of all relevant inputs, outputs, steps, etc.), can then be declared: + +###### Example: Declaring a training workflow & tasks ```json "formulation": { - "workflow": { - "tasks": [ - { - "name": "Train model on dataset X", - "description": "Contains the detailed steps used to train the model on the referenced components (resources)." - "resourceReferences": [ ... ], - "steps": [ ... ], - "inputs": [ ... ], - "outputs": [ ... ], - ... - } - ] - } + ..., + "workflows": [ + { + "name": "Model training workflow", + "description": "Describes the tasks used for training the model described by the ML-BOM." + "tasks": [ + { + "name": "Train model in NVIDIA OCI container", + "description": "Describes the steps used to train the model using commands and libraries in the container image.": [ ... ], + "steps": [ ... ], + "inputs": [ ... ], + "outputs": [ ... ], + ... + } + ] + } + ] +} ``` -Lastly, you would describe the component "stack" as a graph of `runtimeTopology` dependencies. In this case, the training was done using an OCI (Open Container Initiative) standard container image which "provide" a declared set of component libraries (pre-installed on the image): +Lastly, you would describe the component "stack" as a graph of `runtimeTopology` dependencies for the workflow above. In this case, the training was done using an OCI (Open Container Initiative) standard container image which "provide" a declared set of component libraries (pre-installed on the image): + +###### Example: Declaring the runtime topology used for the training workflow tasks ```json "formulation": { - "workflow": { - "runtimeTopology": [ + "workflows": [ + { + "tasks": [ ... ], + ..., + "runtimeTopology": [ { - "ref": "pkg:oci/nvidia-pytorch@sha256:f398a0", - "dependsOn": "nvidia-h100-pcie-gpu-1", - "provides": [ + "ref": "pkg:oci/nvidia-pytorch@sha256:f398a0", + "dependsOn": "nvidia-h100-pcie-gpu-1", + "provides": [ "cuda-toolkit", "pkg:oci/nvidia-pytorch@sha256:f398a0", "pkg:pypi/pytorch@2.10.0", "pkg:generic/nccl@2.29.2" - ] - } - ] - } + ] + } + ] + } + ] +} ``` +###### Field notes + +* **workflows** - In this example, a "training" workflow was shown; however, additional workflows could detail other processes such as "testing" (i.e., model "evaluation"), fine-tuning, and more. +
If there are multiple workflows within the `formulation` object, the subset of components specific to a workflow can optionally be declared using the `resourceReferences` object within the respective `workflow` object. +
\newpage
From 86c5a8195f22bac52f109e2ee4dd93b63c45b79e Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 3 Feb 2026 08:21:22 -0600 Subject: [PATCH 066/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- .../en/0x40-Design-Additional-Model-Information.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 0cf8763..97daa78 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -8,9 +8,13 @@ Currently, the v1.7 CycloneDX specification does not have specific objects or fi For convenience, here are links to the specific sections for some of these acknowledged informational areas: -- [Tokenizers and prompt templates](#tokenizers-and-prompt-templates) -- [Hardware, software & frameworks](#hardware-software--frameworks) -- [Training & testing details](#training--testing-details) +* [Tokenizers and prompt templates](#tokenizers-and-prompt-templates) +* [Including Manufacturing information for the ML model](#including-manufacturing-information-for-the-ml-model) + * [Declaring hardware & software training components](#declaring-hardware--software-training-components) + * [Providing training workflow details](#providing-training-workflow-details) + * [Declaring the runtime topology](#declaring-the-runtime-topology) + +--- ### Tokenizers and prompt templates @@ -89,6 +93,8 @@ For the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model, the chat temp } ``` +* **properties** - Utilizes the reserved CycloneDX property name `cdx:ai-ml:model:template:chat`, with the name widely used `ChatML` template. + --- ### Including Manufacturing information for the ML model @@ -202,6 +208,8 @@ After the hardware and software "stack" of training components have been declare } ``` +#### Declaring the runtime topology + Lastly, you would describe the component "stack" as a graph of `runtimeTopology` dependencies for the workflow above. In this case, the training was done using an OCI (Open Container Initiative) standard container image which "provide" a declared set of component libraries (pre-installed on the image): ###### Example: Declaring the runtime topology used for the training workflow tasks From 2494d0655acf5e415eab410a3006a07173d5ccef Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 3 Feb 2026 09:10:48 -0600 Subject: [PATCH 067/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...x40-Design-Additional-Model-Information.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 97daa78..5d58080 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -8,6 +8,8 @@ Currently, the v1.7 CycloneDX specification does not have specific objects or fi For convenience, here are links to the specific sections for some of these acknowledged informational areas: +* [Supported AI/ML metadata tags](#supported-aiml-metadata-tags) + * [Supported languages]() * [Tokenizers and prompt templates](#tokenizers-and-prompt-templates) * [Including Manufacturing information for the ML model](#including-manufacturing-information-for-the-ml-model) * [Declaring hardware & software training components](#declaring-hardware--software-training-components) @@ -16,6 +18,37 @@ For convenience, here are links to the specific sections for some of these ackno --- +### Supported AI/ML metadata tags + +This section includes discussion and examples of supported AI/ML-related metadata tags that have been found to be used with model cards. + +#### Supported languages + +Models are can be trained in one or more languages (i.e., multilingual models). + +* **Property name**: The CycloneDX reserved property taxonomy name to use to annotate a model with its supported languages is: `cdx:ai-ml:model:languages` + +* **Property value**: The value for this property should be in the form of a comma-separated list of [ISO 639-1 language codes](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) (e.g., `"en,fr,de,it,ja,zh"`, etc.). + +###### Example: Tagging a model with its supported languages + +```json +"component": +{ + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/FakeAI/MultilingualLLama", + ..., + "properties": [ + { + "name": "cdx:ai-ml:model:languages", + "value": "en,fr,de,it,ja,zh" + } + ] +} +``` + +--- + ### Tokenizers and prompt templates Tokenizers provide the preprocessing (encoding) and postprocessing (decoding) functions to convert input and output information to tokens that the associated ML model was trained on and used for inference. From 3fbc2c84bf36d4b4e556fbb6dafdf05fdbce2d72 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 3 Feb 2026 09:13:35 -0600 Subject: [PATCH 068/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ...x40-Design-Additional-Model-Information.md | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 5d58080..c3ee1fa 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -106,22 +106,22 @@ For the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model, the chat temp ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... - "metadata": + ..., + "metadata": + { + "component": { - "component": - { - "type": "machine-learning-model", - "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., - "properties": [ - { - "name": "cdx:ai-ml:model:template:chat", - "value": "ChatML" - } - ] - } + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", + ..., + "properties": [ + { + "name": "cdx:ai-ml:model:template:chat", + "value": "ChatML" + } + ] } + }, ... } ``` @@ -145,14 +145,13 @@ In short, this is accomplished utilizing objects which are part of the [CycloneD First, create entries for all the "components" used in the training process as part of the `formulation` object: ```json -", - "bomFormat": "CycloneDX", - "specVersion": "1.7", +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", ..., "metadata": { "component": { "type": "machine-learning-model", - "bom-ref": "pkg:huggingface/fake.ai/llama3@abcd", + "bom-ref": "pkg:huggingface/FakeAI/llama3@abcd", } }, ..., From 2e576355b5112a92160b9dcc4d662ae78c208a2f Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 3 Feb 2026 09:14:21 -0600 Subject: [PATCH 069/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x40-Design-Additional-Model-Information.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index c3ee1fa..8355188 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -9,7 +9,7 @@ Currently, the v1.7 CycloneDX specification does not have specific objects or fi For convenience, here are links to the specific sections for some of these acknowledged informational areas: * [Supported AI/ML metadata tags](#supported-aiml-metadata-tags) - * [Supported languages]() + * [Model supported languages](#model-supported-languages) * [Tokenizers and prompt templates](#tokenizers-and-prompt-templates) * [Including Manufacturing information for the ML model](#including-manufacturing-information-for-the-ml-model) * [Declaring hardware & software training components](#declaring-hardware--software-training-components) @@ -22,7 +22,7 @@ For convenience, here are links to the specific sections for some of these ackno This section includes discussion and examples of supported AI/ML-related metadata tags that have been found to be used with model cards. -#### Supported languages +#### Model supported languages Models are can be trained in one or more languages (i.e., multilingual models). From b462c50ced8bc026a775a5fea04dbc36ac77c807 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 3 Feb 2026 09:22:40 -0600 Subject: [PATCH 070/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x40-Design-Additional-Model-Information.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 8355188..3f7c91e 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -59,7 +59,9 @@ It is best practice to treat tokenizers and prompt (or chat) templates as annota ###### Example: Declaring and annotating the Qwen-7B model's tokenizer -Using the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model as published to Hugging Face, the tokenizer is published within the model repository and can be represented as components. This method extends the use of a CycloneDX "assembly" to declare the tokenizer as shown in the previous section "[Describing a model repository as a CycloneDX assembly](0x20-Design-Model-Component-Metadata.md#example-qwenqwen-7b-model-repository-files)". +Using the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model in Hugging Face, its tokenizer is published (as a Python file) within the model repository and can be represented as a component. + +Below utilize the CycloneDX "assembly" composition to declare the tokenizer as exampled for other model files in the previous section "[Describing a model repository as a CycloneDX assembly](0x20-Design-Model-Component-Metadata.md#example-qwenqwen-7b-model-repository-files)". ```json { From d76d027dc475a89c06fd321f97898ccfc2cc47f9 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 3 Feb 2026 09:25:05 -0600 Subject: [PATCH 071/111] Author the Considerations sections Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x40-Design-Additional-Model-Information.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 3f7c91e..8300ade 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -59,9 +59,7 @@ It is best practice to treat tokenizers and prompt (or chat) templates as annota ###### Example: Declaring and annotating the Qwen-7B model's tokenizer -Using the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model in Hugging Face, its tokenizer is published (as a Python file) within the model repository and can be represented as a component. - -Below utilize the CycloneDX "assembly" composition to declare the tokenizer as exampled for other model files in the previous section "[Describing a model repository as a CycloneDX assembly](0x20-Design-Model-Component-Metadata.md#example-qwenqwen-7b-model-repository-files)". +Using the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model in Hugging Face, its tokenizer is published (as a Python file) within the model repository and can be represented as a component. We can then utilize the CycloneDX "assembly" composition to declare the tokenizer as a component part of the model. This extends the example from the previous section "[Describing a model repository as a CycloneDX assembly](0x20-Design-Model-Component-Metadata.md#example-qwenqwen-7b-model-repository-files)": ```json { From 0ddcec21c1351fa16906b909e6640cc92c88a81c Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 3 Feb 2026 09:27:09 -0600 Subject: [PATCH 072/111] Editorial cleanup Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x40-Design-Additional-Model-Information.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 8300ade..b493aac 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -12,7 +12,7 @@ For convenience, here are links to the specific sections for some of these ackno * [Model supported languages](#model-supported-languages) * [Tokenizers and prompt templates](#tokenizers-and-prompt-templates) * [Including Manufacturing information for the ML model](#including-manufacturing-information-for-the-ml-model) - * [Declaring hardware & software training components](#declaring-hardware--software-training-components) + * [Declaring hardware and software training components](#declaring-hardware-and-software-training-components) * [Providing training workflow details](#providing-training-workflow-details) * [Declaring the runtime topology](#declaring-the-runtime-topology) @@ -138,7 +138,7 @@ In short, this is accomplished utilizing objects which are part of the [CycloneD **Note**: The "manufacturing" information may be included within the ML-BOM itself or provided as a separate MBOM and cross-linked to each other using the CycloneDX `BOMLink` (see [BOM-Link](https://cyclonedx.org/capabilities/bomlink/) documentation). -#### Declaring hardware & software training components +#### Declaring hardware and software training components ###### Example: Sample methodology for declaring the "training stack" From af85b0b678f76bdf348de075556f0bc3d8329d0c Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 3 Feb 2026 09:31:36 -0600 Subject: [PATCH 073/111] Editorial cleanup Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x40-Design-Additional-Model-Information.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index b493aac..abc94dd 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -8,8 +8,8 @@ Currently, the v1.7 CycloneDX specification does not have specific objects or fi For convenience, here are links to the specific sections for some of these acknowledged informational areas: -* [Supported AI/ML metadata tags](#supported-aiml-metadata-tags) - * [Model supported languages](#model-supported-languages) +* [Using CycloneDX AI/ML metadata tags](#supported-aiml-metadata-tags) + * [Annotating sModel supported languages](#model-supported-languages) * [Tokenizers and prompt templates](#tokenizers-and-prompt-templates) * [Including Manufacturing information for the ML model](#including-manufacturing-information-for-the-ml-model) * [Declaring hardware and software training components](#declaring-hardware-and-software-training-components) @@ -18,9 +18,9 @@ For convenience, here are links to the specific sections for some of these ackno --- -### Supported AI/ML metadata tags +### Using CycloneDX AI/ML metadata tags -This section includes discussion and examples of supported AI/ML-related metadata tags that have been found to be used with model cards. +This section includes discussion and examples of supported AI/ML-related metadata tags that have been found to be used with model cards. These utilize reserved [AI/ML property names](https://github.com/CycloneDX/cyclonedx-property-taxonomy/cdx/ai-ml.md) as part of the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy). #### Model supported languages From 758857cfdd2674385ab83e323b0f1bcdad71485f Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 3 Feb 2026 09:32:36 -0600 Subject: [PATCH 074/111] Editorial cleanup Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x40-Design-Additional-Model-Information.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index abc94dd..a5e5201 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -20,7 +20,7 @@ For convenience, here are links to the specific sections for some of these ackno ### Using CycloneDX AI/ML metadata tags -This section includes discussion and examples of supported AI/ML-related metadata tags that have been found to be used with model cards. These utilize reserved [AI/ML property names](https://github.com/CycloneDX/cyclonedx-property-taxonomy/cdx/ai-ml.md) as part of the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy). +This section includes discussion and examples of supported AI/ML-related metadata tags that have been found to be used with model cards. This method utilizes reserved [AI/ML property names](https://github.com/CycloneDX/cyclonedx-property-taxonomy/cdx/ai-ml.md) registered under the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy). #### Model supported languages From 6e420c0d326bf2fa9380462081266b978d604952 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 3 Feb 2026 10:02:05 -0600 Subject: [PATCH 075/111] Editorial cleanup Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x40-Design-Additional-Model-Information.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index a5e5201..115750f 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -9,9 +9,9 @@ Currently, the v1.7 CycloneDX specification does not have specific objects or fi For convenience, here are links to the specific sections for some of these acknowledged informational areas: * [Using CycloneDX AI/ML metadata tags](#supported-aiml-metadata-tags) - * [Annotating sModel supported languages](#model-supported-languages) + * [Annotating a model's supported languages](#annotating-a-models-supported-languages) * [Tokenizers and prompt templates](#tokenizers-and-prompt-templates) -* [Including Manufacturing information for the ML model](#including-manufacturing-information-for-the-ml-model) +* [Including manufacturing information for the ML model](#including-manufacturing-information-for-the-ml-model) * [Declaring hardware and software training components](#declaring-hardware-and-software-training-components) * [Providing training workflow details](#providing-training-workflow-details) * [Declaring the runtime topology](#declaring-the-runtime-topology) @@ -22,7 +22,7 @@ For convenience, here are links to the specific sections for some of these ackno This section includes discussion and examples of supported AI/ML-related metadata tags that have been found to be used with model cards. This method utilizes reserved [AI/ML property names](https://github.com/CycloneDX/cyclonedx-property-taxonomy/cdx/ai-ml.md) registered under the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy). -#### Model supported languages +#### Annotating a model's supported languages Models are can be trained in one or more languages (i.e., multilingual models). @@ -130,7 +130,7 @@ For the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model, the chat temp --- -### Including Manufacturing information for the ML model +### Including manufacturing information for the ML model This section shows how "manufacturing" (i.e., "training") information is provided relative to the model described by an ML-BOM. From 9ea61b1e1c36465d0fce839efc126253543eb78e Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Tue, 3 Feb 2026 17:04:54 -0600 Subject: [PATCH 076/111] Editorial cleanup Signed-off-by: Matt Rutkowski --- ...x40-Design-Additional-Model-Information.md | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 115750f..aba17ea 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -8,7 +8,7 @@ Currently, the v1.7 CycloneDX specification does not have specific objects or fi For convenience, here are links to the specific sections for some of these acknowledged informational areas: -* [Using CycloneDX AI/ML metadata tags](#supported-aiml-metadata-tags) +* [Using CycloneDX AI/ML metadata tags](#supported-aiml-metadata-properties) * [Annotating a model's supported languages](#annotating-a-models-supported-languages) * [Tokenizers and prompt templates](#tokenizers-and-prompt-templates) * [Including manufacturing information for the ML model](#including-manufacturing-information-for-the-ml-model) @@ -18,9 +18,9 @@ For convenience, here are links to the specific sections for some of these ackno --- -### Using CycloneDX AI/ML metadata tags +### Using CycloneDX AI/ML metadata properties -This section includes discussion and examples of supported AI/ML-related metadata tags that have been found to be used with model cards. This method utilizes reserved [AI/ML property names](https://github.com/CycloneDX/cyclonedx-property-taxonomy/cdx/ai-ml.md) registered under the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy). +This section includes discussion and examples of supported AI/ML-related metadata properties that may be used to classify models as part of their model card information. This method utilizes reserved [AI/ML property names](https://github.com/CycloneDX/cyclonedx-property-taxonomy/cdx/ai-ml.md) registered under the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy). #### Annotating a model's supported languages @@ -47,6 +47,36 @@ Models are can be trained in one or more languages (i.e., multilingual models). } ``` +* **properties** - The `value` reflects the set (list) of ISO ISO 639-1 language codes the model was trained to on and thus capable of understanding as input and generating as output. + +--- + +#### Providing free-form tags for search + +This section describes how to "tag" model components with non-standard keywords and terms seen in various model catalogs or repositories for search or "lookup" purposes. + +###### Example: Tagging a model with its supported languages + +```json +"component": +{ + "type": "machine-learning-model", + "bom-ref": "pkg:huggingface/FakeAI/TxtSpeak3", + ..., + "tags": [ + "pytorch", + "transformers", + "text-to-speech", + "speech-to-speech", + ... + ] +} +``` + +###### Field notes + +* **properties** - The tag values shown above might be used to search for models in a catalog that are compatible with the `pytorch` framework and (the Hugging Face) `transformers` library. The `text-to-speech` and `speech-to-speech` tags could identify the model with those input/output capabilities. + --- ### Tokenizers and prompt templates From c00d91d9de0239fac229a0f06d1b8b74d310aa97 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 4 Feb 2026 08:17:25 -0600 Subject: [PATCH 077/111] Editorial cleanup Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x40-Design-Additional-Model-Information.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index aba17ea..8eee3bd 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -8,7 +8,7 @@ Currently, the v1.7 CycloneDX specification does not have specific objects or fi For convenience, here are links to the specific sections for some of these acknowledged informational areas: -* [Using CycloneDX AI/ML metadata tags](#supported-aiml-metadata-properties) +* [Using CycloneDX AI/ML properties](#using-cyclonedx-aiml-properties) * [Annotating a model's supported languages](#annotating-a-models-supported-languages) * [Tokenizers and prompt templates](#tokenizers-and-prompt-templates) * [Including manufacturing information for the ML model](#including-manufacturing-information-for-the-ml-model) @@ -18,7 +18,7 @@ For convenience, here are links to the specific sections for some of these ackno --- -### Using CycloneDX AI/ML metadata properties +### Using CycloneDX AI/ML properties This section includes discussion and examples of supported AI/ML-related metadata properties that may be used to classify models as part of their model card information. This method utilizes reserved [AI/ML property names](https://github.com/CycloneDX/cyclonedx-property-taxonomy/cdx/ai-ml.md) registered under the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy). From b5eef6f10c8d5aa9a2042932980f46567b0eadc7 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 4 Feb 2026 11:48:26 -0600 Subject: [PATCH 078/111] Editorial cleanup Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 8258d28..0af901a 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -139,11 +139,14 @@ If the model being described by an ML-BOM is instead hosted in a GitHub reposito ###### Example: JSON for model component with GitHub PURL + Note: The derivative `bom-ref`, based upon the PURL is also shown. + ```json "component": { "type": "machine-learning-model", - "bom-ref": "pkg:github/onnx/models/validated/vision/object_detection_segmentation/tiny-yolov2/model@4c46cd0", + "purl": "pkg:github/onnx/models@4c46cd00fbdb7cd30b6c1c17ab54f2e1f4f7b177#validated/vision/object_detection_segmentation/tiny-yolov2/model", + "bom-ref": "pkg:github/onnx/models@244fd47#tiny-yolov2/model" ... } ``` From 40e3e4b229fa33e7abab0a30c6ca5f6ee600b5fc Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 4 Feb 2026 11:48:54 -0600 Subject: [PATCH 079/111] Editorial cleanup Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 0af901a..3e93c67 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -139,7 +139,7 @@ If the model being described by an ML-BOM is instead hosted in a GitHub reposito ###### Example: JSON for model component with GitHub PURL - Note: The derivative `bom-ref`, based upon the PURL is also shown. + **Note**: The derivative `bom-ref`, based upon the PURL, is also shown. ```json "component": From b8a605acfd25606d27af611e3ae8e353893991dc Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 4 Feb 2026 15:48:20 -0600 Subject: [PATCH 080/111] Editorial cleanup Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md | 2 +- ML-BOM/en/0x90-Appendix-A_Glossary.md | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 247ae09..06fb73b 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -129,7 +129,7 @@ The MMLU score from the table would be declared as a performance metric as follo ###### Example: Declaring a GLUE F1 Score -TODO +This example shows how to provide an [F1 score](https://en.wikipedia.org/wiki/F-score) (i.e., the harmonic mean of precision and recall measurements) for a model's performance on classification tasks within the [GLUE benchmark](https://zilliz.com/glossary/glue-benchmark). ```json "quantitativeAnalysis": { diff --git a/ML-BOM/en/0x90-Appendix-A_Glossary.md b/ML-BOM/en/0x90-Appendix-A_Glossary.md index 02e518d..a7f4a4f 100644 --- a/ML-BOM/en/0x90-Appendix-A_Glossary.md +++ b/ML-BOM/en/0x90-Appendix-A_Glossary.md @@ -14,6 +14,12 @@ is an area of artificial intelligence (AI) that enables computers to interpret, [1] [IBM - What is computer vision?](https://www.ibm.com/think/topics/computer-vision) +##### F1 Score + + the F-score or F-measure is a measure of predictive performance. It is calculated from the precision and recall of the test, where the precision is the number of true positive results divided by the number of all samples predicted to be positive. The F1 score is the harmonic mean of the precision and recall symmetrically representing both in one metric. + +[1] [Wikipedia - F1 score](https://en.wikipedia.org/wiki/F-score) + ##### Large Language Model (LLM) A model trained with self-supervised machine learning on a vast amount of text, designed for [Natural Language Processing](#natural-language-processing-nlp) tasks, especially language generation. The largest and most capable LLMs are Generative Pre-trained [Transformers](#transformer) (GPTs) and provide the core capabilities of modern chatbots. LLMs can be fine-tuned for specific tasks or guided by prompt engineering. [1] From a825418ac1b1a976c012bab0b694121c044d6d1a Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 4 Feb 2026 16:19:41 -0600 Subject: [PATCH 081/111] Editorial cleanup Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x91-Appendix-B_References.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index 4cac91a..69bf7d6 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -87,3 +87,11 @@ Note: Most ONNX models have transitioned to and are now registered in Huggingfac * [onnx/DenseNet-121-9](https://huggingface.co/onnx/DenseNet-121-9/tree/main) - `densenet-9.onnx` * GitHub (https://github.com/onnx/models/tree/main/validated/) * [vision/object_detection_segmentation/tiny-yolov2/model](https://github.com/onnx/models/tree/main/validated/vision/object_detection_segmentation/tiny-yolov2/model) - `tinyyolov2-7.onnx` + +--- + +#### Benchmark (dataset) references + +* [MMLU benchmark](https://huggingface.co/datasets/nyu-mll/glue) (Hugging Face - nyu-mll/glue) - MMLU consists of 15,908 multiple-choice questions, with 1,540 of them being used to select and assess optimal settings for models – temperature, batch size and learning rate. The questions span across 57 subjects, from highly complex STEM fields and international law, to nutrition and religion. It was one of the most commonly used benchmarks for comparing the capabilities of large language models. + +* [GLUE benchmark](https://gluebenchmark.com/) (zilliz.com) - The GLUE (General Language Understanding Evaluation) Benchmark is a collection of nine natural language processing (NLP) tasks designed to evaluate the performance of models on a wide range of language understanding challenges. These tasks include textual entailment, sentiment analysis, sentence similarity, and more. \ No newline at end of file From fa42d515c62bb9b2721160ce33856e64e74e8e26 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 4 Feb 2026 16:20:34 -0600 Subject: [PATCH 082/111] Editorial cleanup Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x91-Appendix-B_References.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index 69bf7d6..86cd3d1 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -92,6 +92,8 @@ Note: Most ONNX models have transitioned to and are now registered in Huggingfac #### Benchmark (dataset) references +These are primarily references to benchmarking datasets that have been featured in examples within the guide. + * [MMLU benchmark](https://huggingface.co/datasets/nyu-mll/glue) (Hugging Face - nyu-mll/glue) - MMLU consists of 15,908 multiple-choice questions, with 1,540 of them being used to select and assess optimal settings for models – temperature, batch size and learning rate. The questions span across 57 subjects, from highly complex STEM fields and international law, to nutrition and religion. It was one of the most commonly used benchmarks for comparing the capabilities of large language models. * [GLUE benchmark](https://gluebenchmark.com/) (zilliz.com) - The GLUE (General Language Understanding Evaluation) Benchmark is a collection of nine natural language processing (NLP) tasks designed to evaluate the performance of models on a wide range of language understanding challenges. These tasks include textual entailment, sentiment analysis, sentence similarity, and more. \ No newline at end of file From 74cbc03fadabc376b42fba231eaf1e687b0b6fd6 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Wed, 4 Feb 2026 16:53:18 -0600 Subject: [PATCH 083/111] Add Graphics example for Qwen2 perf. bench. Signed-off-by: Matt Rutkowski --- ...Design-Model-Card-Quantitative-Analysis.md | 30 ++++++++++++------ ML-BOM/en/images/QwenLM-radar_72b.jpg | Bin 0 -> 209533 bytes 2 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 ML-BOM/en/images/QwenLM-radar_72b.jpg diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 06fb73b..ca6574c 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -143,43 +143,51 @@ This example shows how to provide an [F1 score](https://en.wikipedia.org/wiki/F- } ``` +##### Field notes + * **slice** - the `slice` property references a named subset `cola` (Corpus of Linguistic Acceptability) which is a subset of the GLUE tests; "cola" consists of single-sentence task to determine if a sentence is grammatically correct or not. --- #### Graphics -TODO +Model cards typically include graphs, charts and other graphics that highlight the model's performance benchmarks often relative to other models. This section examples the use of the CycloneDX `graphics` object to include a collection of these graphics in the ML-BOM as part of its quantitative analysis information. + +### Example: Qwen model comparative benchmarks + +The [QwenLM/Qwen](https://github.com/QwenLM/Qwen) GitHub repository includes the following JPG format spider diagram showing benchmarking comparisons for their Qwen2 models along with some peer models: + +![Qwen performance benchmarks](images/QwenLM-radar_72b.jpg) -### Example: Graphics +This could be encoded in a CycloneDX ML-BOM model card as follows: ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... + ..., "metadata": { "component": { "type": "machine-learning-model", - ... + ..., "modelCard": { - ... + ..., "quantitativeAnalysis": { + ..., "graphics": [ { "description": "benchmark_score", "collection": [ { - "name": "string", + "name": "Qwen2 Performance Benchmarks (spider diagram)", "image": { - "contentType": "", + "contentType": "image/jpeg", "encoding": "base64", - "content": "string" + "content": "" } } ] - } ] } @@ -189,6 +197,10 @@ TODO } ``` +##### Field notes + +* **encoding** - CycloneDX, currently, only supports a `base64` encoding type. +
\newpage
diff --git a/ML-BOM/en/images/QwenLM-radar_72b.jpg b/ML-BOM/en/images/QwenLM-radar_72b.jpg new file mode 100644 index 0000000000000000000000000000000000000000..743e68fa9e077162f0e93fb85f2d9eb93f90aa24 GIT binary patch literal 209533 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 z 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≪;usSdICy~Pm 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%0D-8-;*Z7T4pgwqKG_P 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 Date: Wed, 4 Feb 2026 17:11:01 -0600 Subject: [PATCH 084/111] Add Graphics example for Qwen2 perf. bench. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x24-Design-Model-Card-Considerations.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 74ac74e..195d516 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -229,10 +229,9 @@ This example shows how fairness assessment information would be included in a a "mitigationStrategy": "Researchers recommend using Reinforcement Learning from Artificial Intelligence Feedback (RLAIF) and rule-based rewards to align the model with specific legal standards like the EU AI Act." }, { - "groupAtRisk": "", - "benefits": "", - "harms": "", - "mitigationStrategy": "" + "groupAtRisk": "Non-English/Non-Chinese speakers, speakers of regional dialects or specific geographic regions (e.g., Southeast Asia or the Middle East) on thinking or \"reasoning\" tasks.", + "harms": "Quality-of-Service Harm: The model may provide high-quality, nuanced reasoning in English or Mandarin but offer oversimplified, factually incorrect, or \"hallucinated\" information when queried in other supported languages.", + "mitigationStrategy": "Cross-Lingual Alignment: Developers can use multilingual Supervised Fine-Tuning (SFT). By training on additional high-quality, parallel corpora from other languages on \"reasoning capabilities\" (e.g., logic, math, coding)." }, ... ] From a3f91db396cd9102d7443a6fe14099f9eb960101 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 10:13:50 -0600 Subject: [PATCH 085/111] Add Graphics example for Qwen2 perf. bench. Signed-off-by: Matt Rutkowski --- .../0x20-Design-Model-Component-Metadata.md | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 3e93c67..c85c17d 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -129,8 +129,6 @@ This section provides best practice guidance on how the component fields were fi - **vcs** - Provides a link to the version control system (i.e., the model provider aka. `supplier`). In this example, this is Hugging Face and affirms the associated PURL identifier. - **model-card** - Provides a link to the model's Hugging Face model card which is comprised of mostly unstructured information in the form of a markdown file (i.e., README.md).
*The CycloneDX representation of model card information will be detailed in a subsequent section.* - - #### Model identifier(s) As you can see in the above example, the `component` has a `bom-ref` that is also a valid [Package URL (PURL)](https://github.com/package-url/purl-spec) for a ["Qwen-7B" model hosted in a Huggingface model repository](https://huggingface.co/Qwen/Qwen-7B) using the [Hugging Face PURL type](https://github.com/package-url/purl-spec/blob/main/types-doc/huggingface-definition.md). When a valid `purl` value is available for a model, it is recommended that it also be used as its component's `bom-ref`. @@ -323,6 +321,52 @@ then the model component's new hierarchy of composing files would be described a --- +### Declaring a model's pedigree + +ML models are often derived from existing, pre-trained models to +optimize performance, reduce resource consumption, and adapt to specialized tasks without training from scratch. Some reasons for this include: + +* **Fine-Tuning:**: Specialized adaptation where a general model (e.g., LLM) is retrained on a smaller, targeted dataset to improve performance for specific domains. +* **Quantization**: Reduces model size and increases inference speed by mapping parameters to lower-precision tensor formats (e.g., FP32 to Q4_K_M precision), which also lowers energy consumption for edge devices. +* **Format Conversions**: Transforming models between frameworks (e.g., PyTorch to ONNX) ensures interoperability, allowing deployment on different frameworks and accelerators. +* **Pruning**: Derives a smaller model by removing redundant or less important parameters (weights) that do not significantly contribute to output accuracy. +* **Adapters**: Adding small, trainable layers (adapters) to a frozen base model to adapt it to new tasks without changing the original, large model weights, saving on storage for multi-task scenarios. + +It is important to capture any of these transformations as the model's lineage or "pedigree" or within an ML-BOM. This should be accomplished via the CycloneDX `pedigree` object and describing a model's `ancestors` as a hierarchical graph. + +###### Example: Declaring the finetuning of llama3 model for a coding variant + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + ..., + "metadata": { + "component": { + "type": "machine-learning-model", + "name": "unsloth/Llama-3.2-3B-Instruct", + "purl": "pkg:huggingface/unsloth/Llama-3.2-3B-Instruct@1.0.0", + "bom-ref": "pkg:huggingface/unsloth/Llama-3.2-3B-Instruct@1.0.0", + "publisher": "Unsloth", + "description": "A pre-optimized, specialized versions of the meta-llama/Llama-3.2-3B-Instruct model designed to work seamlessly with Unsloth's training framework", + ..., + "pedigree": { + "ancestors": [ + { + "type": "machine-learning-model", + "name": "meta-llama/Llama-3.2-3B-Instruct", + "publisher": "Meta", + "purl": "pkg:huggingface/meta-llama/Llama-3.2-3B-Instruct", + "description": "The original base model from Meta Llama used for fine-tuning." + } + ] + } + } + } +} +``` + +* **Note**: If at the time an ML-BOM is created for a model its downstream model variants (e.g., finetunings, quantizations, etc. derived from the model) are known, these can also be recorded within the `pedigree` object as `descendants`. +

From b8a652d30e413f79970db723a8e1ea3a22f5f2df Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 10:15:13 -0600 Subject: [PATCH 086/111] Add Graphics example for Qwen2 perf. bench. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index c85c17d..611856c 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -12,11 +12,12 @@ The [Core Concepts](0x15-Core-Concepts.md#key-components-of-an-ml-bom) listed in For convenience, here are links to the specific sections for each of those informational areas: -- [Anatomy of an ML-BOM](#anatomy-of-an-ml-bom) - - [Describing models as components](#describing-models-as-components) - - [Model repositories as components](#model-repositories-as-components) - - [Model identifiers](#model-identifiers) - - [Model metadata](#model-metadata) +* [Anatomy of an ML-BOM](#anatomy-of-an-ml-bom) + * [Describing models as components](#describing-models-as-components) + * [Model repositories as components](#model-repositories-as-components) + * [Model identifiers](#model-identifiers) + * [Model metadata](#model-metadata) + * [Declaring a model's pedigree](#declaring-a-models-pedigree) --- @@ -24,7 +25,6 @@ For convenience, here are links to the specific sections for each of those infor In CycloneDX, a model is considered a `component` where general best practices for providing information such as component identification, metadata, provenance, pedigree, etc. should be followed as documented in the [CycloneDX Authoritative Guide to SBOM](https://cyclonedx.org/guides/OWASP_CycloneDX-Authoritative-Guide-to-SBOM-en.pdf). - ![Diagram: Anatomy of an ML-BOM](images/anatomy.svg) --- From 23b90b8dbcb38c5b9f98174721cf5e39de04288b Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 10:40:36 -0600 Subject: [PATCH 087/111] Add Graphics example for Qwen2 perf. bench. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 4 ++-- ML-BOM/en/0x90-Appendix-A_Glossary.md | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 611856c..6a3dd0a 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -16,7 +16,7 @@ For convenience, here are links to the specific sections for each of those infor * [Describing models as components](#describing-models-as-components) * [Model repositories as components](#model-repositories-as-components) * [Model identifiers](#model-identifiers) - * [Model metadata](#model-metadata) + * [Describing a model repository as a CycloneDX assembly](#describing-a-model-repository-as-a-cyclonedx-assembly) * [Declaring a model's pedigree](#declaring-a-models-pedigree) --- @@ -327,7 +327,7 @@ ML models are often derived from existing, pre-trained models to optimize performance, reduce resource consumption, and adapt to specialized tasks without training from scratch. Some reasons for this include: * **Fine-Tuning:**: Specialized adaptation where a general model (e.g., LLM) is retrained on a smaller, targeted dataset to improve performance for specific domains. -* **Quantization**: Reduces model size and increases inference speed by mapping parameters to lower-precision tensor formats (e.g., FP32 to Q4_K_M precision), which also lowers energy consumption for edge devices. +* **Quantization**: Reduces model size and increases inference speed by mapping parameters to lower-precision tensor formats (e.g., from [`FP32`](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) to `int8` or `Q4_K_M` precision), which also lowers energy consumption for edge devices. * **Format Conversions**: Transforming models between frameworks (e.g., PyTorch to ONNX) ensures interoperability, allowing deployment on different frameworks and accelerators. * **Pruning**: Derives a smaller model by removing redundant or less important parameters (weights) that do not significantly contribute to output accuracy. * **Adapters**: Adding small, trainable layers (adapters) to a frozen base model to adapt it to new tasks without changing the original, large model weights, saving on storage for multi-task scenarios. diff --git a/ML-BOM/en/0x90-Appendix-A_Glossary.md b/ML-BOM/en/0x90-Appendix-A_Glossary.md index a7f4a4f..d59e6f5 100644 --- a/ML-BOM/en/0x90-Appendix-A_Glossary.md +++ b/ML-BOM/en/0x90-Appendix-A_Glossary.md @@ -43,6 +43,7 @@ the process of structuring or crafting an instruction in order to produce better A technique to reduce the computational and memory costs of running inference by representing the ([tensor](#tensor)) weights and [activations](#activation-function) with low-precision data types like 8-bit integer (int8) instead of the usual 32-bit floating point (float32). [1] [1] [Hugging Face - Quantization](https://huggingface.co/docs/optimum/en/concept_guides/quantization#quantization) +[2] [GGUF - Quantization types](https://huggingface.co/docs/hub/en/gguf#quantization-types) ##### Tensor From 3d0b3ad714e890ed106d517dfa79b9eaacce19c2 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 10:41:11 -0600 Subject: [PATCH 088/111] Add Graphics example for Qwen2 perf. bench. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 6a3dd0a..3f7853c 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -323,8 +323,7 @@ then the model component's new hierarchy of composing files would be described a ### Declaring a model's pedigree -ML models are often derived from existing, pre-trained models to -optimize performance, reduce resource consumption, and adapt to specialized tasks without training from scratch. Some reasons for this include: +ML models are often derived from existing, pre-trained models to optimize performance, reduce resource consumption, and adapt to specialized tasks without training from scratch. Some reasons for this include: * **Fine-Tuning:**: Specialized adaptation where a general model (e.g., LLM) is retrained on a smaller, targeted dataset to improve performance for specific domains. * **Quantization**: Reduces model size and increases inference speed by mapping parameters to lower-precision tensor formats (e.g., from [`FP32`](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) to `int8` or `Q4_K_M` precision), which also lowers energy consumption for edge devices. From e6b322b5abcbd6e4eba6a30b226fa946fc185588 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 10:57:29 -0600 Subject: [PATCH 089/111] Final edits, cleanup, link validation, etc. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x21-Design-Model-Card-Overview.md | 60 +++++++------- ...Design-Model-Card-Quantitative-Analysis.md | 6 +- ...x40-Design-Additional-Model-Information.md | 3 + SaaSBOM/en/0x10-Introduction.md | 82 ++++++------------- 4 files changed, 63 insertions(+), 88 deletions(-) diff --git a/ML-BOM/en/0x21-Design-Model-Card-Overview.md b/ML-BOM/en/0x21-Design-Model-Card-Overview.md index 0eced21..acb5e47 100644 --- a/ML-BOM/en/0x21-Design-Model-Card-Overview.md +++ b/ML-BOM/en/0x21-Design-Model-Card-Overview.md @@ -12,36 +12,36 @@ This section describes the design and best practices when providing information For convenience, here are links to the specific sections for each of those informational areas: ->[!TODO] add hyperlinks when done with all subsections - -- [Model parameters](0x22-Design-Model-Card-Parameters.md#model-parameters) - - [Model metadata](0x22-Design-Model-Card-Parameters.md#model-metadata) - - [Approach](0x22-Design-Model-Card-Parameters.md#approach) - - [Task](0x22-Design-Model-Card-Parameters.md#task) - - [Architecture family](0x22-Design-Model-Card-Parameters.md#architecture-family) - - [Model architecture](0x22-Design-Model-Card-Parameters.md#model-architecture) - - [Datasets](0x22-Design-Model-Card-Parameters.md#datasets) - - [Inputs & Outputs](0x22-Design-Model-Card-Parameters.md#inputs--outputs) - - [Declaring other properties](0x22-Design-Model-Card-Parameters.md#declaring-other-properties) - - [Configuration parameters & hyperparameters](0x22-Design-Model-Card-Parameters.md#configuration-parameters--hyperparameters) - -- [Quantitative analysis](0x23-Design-Model-Card-Quantitative-Analysis.md#quantitative-analysis) - - [Performance metrics](0x23-Design-Model-Card-Quantitative-Analysis.md#performance-metrics) - - [Graphics](0x23-Design-Model-Card-Quantitative-Analysis.md#graphics) - -- [Considerations](0x24-Design-Model-Card-Considerations.md#considerations) - - [Users & use cases](0x24-Design-Model-Card-Considerations.md#users--use-cases) - - [Technical limitations](0x24-Design-Model-Card-Considerations.md#technical-limitations) - - [Performance tradeoffs](0x24-Design-Model-Card-Considerations.md#performance-tradeoffs) - - [Fairness assessments](0x24-Design-Model-Card-Considerations.md#fairness-assessments) - - [Ethical considerations](0x24-Design-Model-Card-Considerations.md#ethical-considerations) - - [Environmental impact consideration](0x24-Design-Model-Card-Considerations.md#environmental-considerations) - -- [Additional model information](0x40-Design-Additional-Model-Information.md#additional-model-related-information) - - [Tokenizers and prompt templates](0x40-Design-Additional-Model-Information.md#tokenizers-and-prompt-templates) - - [Hardware, software & frameworks](0x40-Design-Additional-Model-Information.md#hardware-software--frameworks) - - [Training & testing details](0x40-Design-Additional-Model-Information.md#training--testing-details) - - [Intended use & ethics](0x40-Design-Additional-Model-Information.md#intended-use--ethics) +* [Model parameters](0x22-Design-Model-Card-Parameters.md#model-parameters) + * [Model metadata](0x22-Design-Model-Card-Parameters.md#model-metadata) + * [Approach](0x22-Design-Model-Card-Parameters.md#approach) + * [Task](0x22-Design-Model-Card-Parameters.md#task) + * [Architecture family](0x22-Design-Model-Card-Parameters.md#architecture-family) + * [Model architecture](0x22-Design-Model-Card-Parameters.md#model-architecture) + * [Datasets](0x22-Design-Model-Card-Parameters.md#datasets) + * [Inputs & Outputs](0x22-Design-Model-Card-Parameters.md#inputs--outputs) + * [Declaring other properties](0x22-Design-Model-Card-Parameters.md#declaring-other-properties) + * [Configuration parameters & hyperparameters](0x22-Design-Model-Card-Parameters.md#configuration-parameters--hyperparameters) + +* [Quantitative analysis](0x23-Design-Model-Card-Quantitative-Analysis.md#quantitative-analysis) + * [Metrics](0x23-Design-Model-Card-Quantitative-Analysis.md#metrics) + * [Performance metrics](0x23-Design-Model-Card-Quantitative-Analysis.md#performance-metrics) + * [Graphics](0x23-Design-Model-Card-Quantitative-Analysis.md#graphics) + +* [Considerations](0x24-Design-Model-Card-Considerations.md#considerations) + * [Users & use cases](0x24-Design-Model-Card-Considerations.md#users--use-cases) + * [Technical limitations](0x24-Design-Model-Card-Considerations.md#technical-limitations) + * [Performance tradeoffs](0x24-Design-Model-Card-Considerations.md#performance-tradeoffs) + * [Fairness assessments](0x24-Design-Model-Card-Considerations.md#fairness-assessments) + * [Ethical considerations](0x24-Design-Model-Card-Considerations.md#ethical-considerations) + * [Environmental impact consideration](0x24-Design-Model-Card-Considerations.md#environmental-considerations) + * [Energy consumptions](0x24-Design-Model-Card-Considerations.md#energy-consumptions) + +* [Additional model information](0x40-Design-Additional-Model-Information.md#additional-model-related-information) + * [Tokenizers and prompt templates](0x40-Design-Additional-Model-Information.md#tokenizers-and-prompt-templates) + * [Using CycloneDX AI/ML properties](0x40-Design-Additional-Model-Information.md#using-cyclonedx-aiml-properties) + * [Training & testing details](0x40-Design-Additional-Model-Information.md#training--testing-details) + * [Intended use & ethics](0x40-Design-Additional-Model-Information.md#intended-use--ethics) #### Design notes diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index ca6574c..3349eb0 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -143,7 +143,7 @@ This example shows how to provide an [F1 score](https://en.wikipedia.org/wiki/F- } ``` -##### Field notes +###### Field notes * **slice** - the `slice` property references a named subset `cola` (Corpus of Linguistic Acceptability) which is a subset of the GLUE tests; "cola" consists of single-sentence task to determine if a sentence is grammatically correct or not. @@ -153,7 +153,7 @@ This example shows how to provide an [F1 score](https://en.wikipedia.org/wiki/F- Model cards typically include graphs, charts and other graphics that highlight the model's performance benchmarks often relative to other models. This section examples the use of the CycloneDX `graphics` object to include a collection of these graphics in the ML-BOM as part of its quantitative analysis information. -### Example: Qwen model comparative benchmarks +###### Example: Qwen model comparative benchmarks The [QwenLM/Qwen](https://github.com/QwenLM/Qwen) GitHub repository includes the following JPG format spider diagram showing benchmarking comparisons for their Qwen2 models along with some peer models: @@ -197,7 +197,7 @@ This could be encoded in a CycloneDX ML-BOM model card as follows: } ``` -##### Field notes +###### Field notes * **encoding** - CycloneDX, currently, only supports a `base64` encoding type. diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 8eee3bd..75a6b03 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -10,6 +10,7 @@ For convenience, here are links to the specific sections for some of these ackno * [Using CycloneDX AI/ML properties](#using-cyclonedx-aiml-properties) * [Annotating a model's supported languages](#annotating-a-models-supported-languages) + * [Providing free-form tags for search](#providing-free-form-tags-for-search) * [Tokenizers and prompt templates](#tokenizers-and-prompt-templates) * [Including manufacturing information for the ML model](#including-manufacturing-information-for-the-ml-model) * [Declaring hardware and software training components](#declaring-hardware-and-software-training-components) @@ -47,6 +48,8 @@ Models are can be trained in one or more languages (i.e., multilingual models). } ``` +###### Field notes + * **properties** - The `value` reflects the set (list) of ISO ISO 639-1 language codes the model was trained to on and thus capable of understanding as input and generating as output. --- diff --git a/SaaSBOM/en/0x10-Introduction.md b/SaaSBOM/en/0x10-Introduction.md index aac63a6..467d9c3 100644 --- a/SaaSBOM/en/0x10-Introduction.md +++ b/SaaSBOM/en/0x10-Introduction.md @@ -1,14 +1,8 @@ # Introduction -CycloneDX is a modern standard for the software supply chain. At its core, CycloneDX is a general-purpose Bill of -Materials (BOM) standard capable of representing software, hardware, services, and other types of inventory. The CycloneDX -standard began in 2017 in the Open Worldwide Application Security Project (OWASP) community. CycloneDX is an OWASP -flagship project, has a formal standardization process and governance model, and is supported by the global information -security community. +CycloneDX is a modern standard for the software supply chain. At its core, CycloneDX is a general-purpose Bill of Materials (BOM) standard capable of representing software, hardware, services, and other types of inventory. The CycloneDX standard began in 2017 in the Open Worldwide Application Security Project (OWASP) community. CycloneDX is an OWASP flagship project, has a formal standardization process and governance model, and is supported by the global information security community. ## Design Philosophy and Guiding Principles -The simplicity of design is at the forefront of the CycloneDX philosophy. The format is easily understandable by a wide -range of technical and non-technical roles. CycloneDX is a full-stack BOM format with many advanced capabilities that -are achieved without sacrificing the design philosophy. Some guiding principles influencing its design include: +The simplicity of design is at the forefront of the CycloneDX philosophy. The format is easily understandable by a wide range of technical and non-technical roles. CycloneDX is a full-stack BOM format with many advanced capabilities that are achieved without sacrificing the design philosophy. Some guiding principles influencing its design include: * Be easy to adopt and easy to contribute to * Identify risk to as many adopters as possible, as quickly as possible @@ -19,16 +13,13 @@ are achieved without sacrificing the design philosophy. Some guiding principles * Focus on high degrees of automation * Provide a smooth path to specification compliance through prescriptive design -## High-Level SaaSBOM Use Cases - -TODO - ## xBOM Capabilities CycloneDX provides advanced supply chain capabilities for cyber risk reduction. Among these capabilities are: * Software Bill of Materials (SBOM) * Software-as-a-Service Bill of Materials (SaaSBOM) * Hardware Bill of Materials (HBOM) +* Cryptographic Bill of Materials (CBOM) * Machine Learning Bill of Materials (ML-BOM) * Operations Bill of Materials (OBOM) * Manufacturing Bill of Materials (MBOM) @@ -42,69 +33,50 @@ CycloneDX provides advanced supply chain capabilities for cyber risk reduction.
### Software Bill of Materials (SBOM) -SBOMs describe the inventory of software components and services and the dependency relationships between them. -A complete and accurate inventory of all first-party and third-party components is essential for risk identification. -SBOMs should ideally contain all direct and transitive components and the dependency relationships between them. + +SBOMs describe the inventory of software components and services and the dependency relationships between them. A complete and accurate inventory of all first-party and third-party components is essential for risk identification. SBOMs should ideally contain all direct and transitive components and the dependency relationships between them. ### Software-as-a-Service BOM (SaaSBOM) -SaaSBOMs provide an inventory of services, endpoints, and data flows and classifications that power cloud-native applications. -CycloneDX is capable of describing any type of service, including microservices, Service Orientated Architecture (SOA), -Function as a Service (FaaS), and System of Systems. -SaaSBOMs complement Infrastructure-as-Code (IaC) by providing a logical representation of a complex system, complete -with an inventory of all services, their reliance on other services, endpoint URLs, data classifications, and the directional -flow of data between services. Optionally, SaaSBOMs may also include the software components that make up each service. +SaaSBOMs provide an inventory of services, endpoints, and data flows and classifications that power cloud-native applications. CycloneDX is capable of describing any type of service, including microservices, Service Orientated Architecture (SOA), Function as a Service (FaaS), and System of Systems. + +SaaSBOMs complement Infrastructure-as-Code (IaC) by providing a logical representation of a complex system, complete with an inventory of all services, their reliance on other services, endpoint URLs, data classifications, and the directional flow of data between services. Optionally, SaaSBOMs may also include the software components that make up each service. ### Hardware Bill of Materials (HBOM) -CycloneDX supports many types of components, including hardware devices, making it ideal for use with consumer -electronics, IoT, ICS, and other types of embedded devices. CycloneDX fills an important role in between traditional -eBOM and mBOM use cases for hardware devices. + +CycloneDX supports many types of components, including hardware devices, making it ideal for use with consumer electronics, IoT, ICS, and other types of embedded devices. CycloneDX fills an important role in between traditional eBOM and mBOM use cases for hardware devices. + +### Cryptographic Bill of Materials (CBOM) + +Support for CBOM is included in CycloneDX v1.6 and higher. Discovering, managing, and reporting on cryptographic assets is necessary as the first step on the migration journey to quantum-safe systems and applications. ### Machine Learning Bill of Materials (ML-BOM) -ML-BOMs provide transparency for machine learning models and datasets, which provide visibility into possible security, -privacy, safety, and ethical considerations. CycloneDX standardizes model cards in a way where the inventory of models -and datasets can be used independently or combined with the inventory of software and hardware components or services -defined in HBOMs, SBOMs, and SaaSBOMs. + +ML-BOMs provide transparency for machine learning models and datasets, which provide visibility into possible security, privacy, safety, and ethical considerations. CycloneDX standardizes model cards in a way where the inventory of models and datasets can be used independently or combined with the inventory of software and hardware components or services defined in HBOMs, SBOMs, and SaaSBOMs. ### Operations Bill of Materials (OBOM) -OBOMs provide a full-stack inventory of runtime environments, configurations, and additional dependencies. CycloneDX is a -full-stack bill of materials standard supporting entire runtime environments consisting of hardware, firmware, containers, -operating systems, applications, and libraries. Coupled with the ability to specify configuration makes CycloneDX -ideal for Operations Bill of Materials. + +OBOMs provide a full-stack inventory of runtime environments, configurations, and additional dependencies. CycloneDX is a full-stack bill of materials standard supporting entire runtime environments consisting of hardware, firmware, containers, operating systems, applications, and libraries. Coupled with the ability to specify configuration makes CycloneDX ideal for Operations Bill of Materials. ### Manufacturing Bill of Materials (MBOM) -CycloneDX can describe declared and observed formulations for reproducibility throughout the product lifecycle of components -and services. This advanced capability provides transparency into how components were made, how a model was trained, or -how a service was created or deployed. In addition, every component and service in a CycloneDX BOM can optionally specify -formulation and do so in existing BOMs or in dedicated MBOMs. By externalizing formulation into dedicated MBOMs, SBOMs -can link to MBOMs for their components and services, and access control can be managed independently. This allows -organizations to maintain tighter control over what parties gain access to inventory information in a BOM and what parties -have access to MBOM information which may have higher sensitivity and data classification. + +CycloneDX can describe declared and observed formulations for reproducibility throughout the product lifecycle of components and services. This advanced capability provides transparency into how components were made, how a model was trained, or how a service was created or deployed. In addition, every component and service in a CycloneDX BOM can optionally specify formulation and do so in existing BOMs or in dedicated MBOMs. By externalizing formulation into dedicated MBOMs, SBOMs can link to MBOMs for their components and services, and access control can be managed independently. This allows organizations to maintain tighter control over what parties gain access to inventory information in a BOM and what parties have access to MBOM information which may have higher sensitivity and data classification. ### Bill of Vulnerabilities (BOV) -CycloneDX BOMs may consist solely of vulnerabilities and thus can be used to share vulnerability data between systems -and sources of vulnerability intelligence. Complex vulnerability data can be represented, including the vulnerability -source, references, multiple severities, risk ratings, details and recommendations, and the affected software and -hardware, along with their versions. + +CycloneDX BOMs may consist solely of vulnerabilities and thus can be used to share vulnerability data between systems and sources of vulnerability intelligence. Complex vulnerability data can be represented, including the vulnerability source, references, multiple severities, risk ratings, details and recommendations, and the affected software and hardware, along with their versions. ### Vulnerability Disclosure Report (VDR) -VDRs communicate known and unknown vulnerabilities affecting components and services. Known vulnerabilities inherited -from the use of third-party and open-source software can be communicated with CycloneDX. Previously unknown vulnerabilities -affecting both components and services may also be disclosed using CycloneDX, making it ideal for Vulnerability Disclosure -Report (VDR) use cases. CycloneDX exceeds the data field requirements defined in -[ISO/IEC 29147:2018](https://www.iso.org/standard/72311.html) for vulnerability disclosure information. + +VDRs communicate known and unknown vulnerabilities affecting components and services. Known vulnerabilities inherited from the use of third-party and open-source software can be communicated with CycloneDX. Previously unknown vulnerabilities affecting both components and services may also be disclosed using CycloneDX, making it ideal for Vulnerability Disclosure Report (VDR) use cases. CycloneDX exceeds the data field requirements defined in [ISO/IEC 29147:2018](https://www.iso.org/standard/72311.html) for vulnerability disclosure information. ### Vulnerability Exploitability eXchange (VEX) -VEX conveys the exploitability of vulnerable components in the context of the product in which they're used. VEX is a -subset of VDR. Oftentimes, products are not affected by a vulnerability simply by including an otherwise vulnerable -component. VEX allows software vendors and other parties to communicate the exploitability status of vulnerabilities, -providing clarity on the vulnerabilities that pose a risk and the ones that do not. + +VEX conveys the exploitability of vulnerable components in the context of the product in which they're used. VEX is a subset of VDR. Oftentimes, products are not affected by a vulnerability simply by including an otherwise vulnerable component. VEX allows software vendors and other parties to communicate the exploitability status of vulnerabilities, providing clarity on the vulnerabilities that pose a risk and the ones that do not. ### Common Release Notes Format -CycloneDX standardizes release notes into a common, machine-readable format. This capability unlocks new workflow -potential for software publishers and consumers alike. This functionality works with or without the Bill of Materials -capabilities of the specification. +CycloneDX standardizes release notes into a common, machine-readable format. This capability unlocks new workflow potential for software publishers and consumers alike. This functionality works with or without the Bill of Materials capabilities of the specification.
\newpage From c47bf630219293334071988f560e2b6d428beed5 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 11:24:38 -0600 Subject: [PATCH 090/111] Final edits, cleanup, link validation, etc. Signed-off-by: Matt Rutkowski --- Attestations/en/0x10-Introduction.md | 17 +++++----- ML-BOM/en/0x21-Design-Model-Card-Overview.md | 31 +++++++++---------- .../en/0x22-Design-Model-Card-Parameters.md | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Attestations/en/0x10-Introduction.md b/Attestations/en/0x10-Introduction.md index cf21491..2790b15 100644 --- a/Attestations/en/0x10-Introduction.md +++ b/Attestations/en/0x10-Introduction.md @@ -1,8 +1,8 @@ # Introduction CycloneDX Attestations is a modern standard for security compliance. It enables organizations to use a machine-readable format for communication about security standards, claims, and evidence about security requirements, as well as attestations to the veracity and completeness of those claims. You can think of Attestations as a way to manage "compliance as code." The Attestations project began in 2023 as part of the broader CycloneDX project. -CycloneDX Attestations is part of OWASP CycloneDX. CycloneDX is an OWASP flagship project, has a formal standardization -process and governance model through [Ecma Technical Committee 54](https://tc54.org), and is supported by the global +CycloneDX Attestations is part of OWASP CycloneDX. CycloneDX is an OWASP flagship project, has a formal standardization +process and governance model through [Ecma Technical Committee 54](https://tc54.org), and is supported by the global information security community. ## Intended Audience @@ -36,12 +36,13 @@ We believe: ## Intended Use Cases CycloneDX Attestations provides a non-repudiatable way to communicate compliance to standards. It is intended to be used in a variety of use cases, including: -* Standard authorities - Authors of security standards that want to create a machine-readable version of their requirements. E.g., CycloneDX may be used to represent the requirements of the OWASP Software Security Framework. NIST may use CycloneDX to represent the requirements of CISA attestations form for federal agencies. -* Providers in highly regulated verticals - Adherence to existing regulatory and industry compliance requirements like PCI DSS, HIPAA, NIST, etc. CycloneDX can be used to provide non-repudiatable evidence of compliance. -* Providers who want to build trust with their customers by demonstrating compliance with a specific security standard - Adherence to a specific security standard like ISO 27001, NIST 800-53, etc. -* Policy as code in Governance, Risk, and Compliance (GRC) teams - GRC teams may use CycloneDX to represent internal policies and security standards requirements. This can be used to automate the compliance process, collect and manage evidence of compliance. This can in turn be used to estimate the risk of non-compliance and provide assurance to the board and other stakeholders. -* Evidence as code for Engineering teams - CycloneDX makes it easy for engineering teams to collect and manage evidence of compliance with internal security standards. Engineering teams can automate the process of collecting evidence and provide assurance to the security and GRC team that they are compliant with the internal security standards. -* Consumers who want to restrict the use of software to only those that meet specific security standards - Consumers of software may use CycloneDX to ensure that the software they are using meets specific security standards. This can be used to reduce the risk of using software that does not meet specific security standards. + +* **Standard authorities**: Authors of security standards that want to create a machine-readable version of their requirements. For example, CycloneDX may be used to represent the requirements of the U.S. Cybersecurity Infrastructure Security Agency's [CISA Secure Software Attestation Form](https://www.cisa.gov/secure-software-attestation-form) for federal agencies or information required by the [EU Artificial Intelligence (AI) Act](https://artificialintelligenceact.eu/). +* **Providers in highly regulated verticals**: Adherence to existing regulatory and industry compliance requirements like [PCI DSS](https://www.pcisecuritystandards.org/standards/pci-dss/), [HIPAA](https://www.hhs.gov/hipaa/index.html), [NIST](https://www.nist.gov/), etc. CycloneDX can be used to provide non-repudiatable evidence of compliance. +* **Providers building customer trust**: Providers who wish to demonstrate compliance with a specific security standard and/or adherence to a specific security standard via references, evidence and other information provided within BOMs. +* **Governance, Risk, and Compliance (GRC) teams**: GRC teams who want to use CycloneDX to assess adherence to their policies, security standards and requirements as well as supporting the automation of compliance processes. +* **Engineering teams** - Engineering teams who collect and manage evidence of compliance with internal security standards using CycloneDX BOMs. +* **Consumers** who want to restrict the use of AI/ML software and models to only those that meet specific security standards. ## Tool Support Over time, we expect tools to emerge to manage all aspects of security attestation. As a producer, imagine being able to select appropriate standards for a project, eliminate duplication, articulate compliance rationales, automatically generate and include supporting evidence, manage reviews, and digitally sign attestations. From the assessor's point of view, imagine being able to quickly evaluate claims and evidence, easily identify changes, point out gaps, and digitally sign approvals. diff --git a/ML-BOM/en/0x21-Design-Model-Card-Overview.md b/ML-BOM/en/0x21-Design-Model-Card-Overview.md index acb5e47..5002504 100644 --- a/ML-BOM/en/0x21-Design-Model-Card-Overview.md +++ b/ML-BOM/en/0x21-Design-Model-Card-Overview.md @@ -24,24 +24,23 @@ For convenience, here are links to the specific sections for each of those infor * [Configuration parameters & hyperparameters](0x22-Design-Model-Card-Parameters.md#configuration-parameters--hyperparameters) * [Quantitative analysis](0x23-Design-Model-Card-Quantitative-Analysis.md#quantitative-analysis) - * [Metrics](0x23-Design-Model-Card-Quantitative-Analysis.md#metrics) - * [Performance metrics](0x23-Design-Model-Card-Quantitative-Analysis.md#performance-metrics) - * [Graphics](0x23-Design-Model-Card-Quantitative-Analysis.md#graphics) + * [Metrics](0x23-Design-Model-Card-Quantitative-Analysis.md#metrics) + * [Performance metrics](0x23-Design-Model-Card-Quantitative-Analysis.md#performance-metrics) + * [Graphics](0x23-Design-Model-Card-Quantitative-Analysis.md#graphics) * [Considerations](0x24-Design-Model-Card-Considerations.md#considerations) - * [Users & use cases](0x24-Design-Model-Card-Considerations.md#users--use-cases) - * [Technical limitations](0x24-Design-Model-Card-Considerations.md#technical-limitations) - * [Performance tradeoffs](0x24-Design-Model-Card-Considerations.md#performance-tradeoffs) - * [Fairness assessments](0x24-Design-Model-Card-Considerations.md#fairness-assessments) - * [Ethical considerations](0x24-Design-Model-Card-Considerations.md#ethical-considerations) - * [Environmental impact consideration](0x24-Design-Model-Card-Considerations.md#environmental-considerations) - * [Energy consumptions](0x24-Design-Model-Card-Considerations.md#energy-consumptions) - -* [Additional model information](0x40-Design-Additional-Model-Information.md#additional-model-related-information) - * [Tokenizers and prompt templates](0x40-Design-Additional-Model-Information.md#tokenizers-and-prompt-templates) - * [Using CycloneDX AI/ML properties](0x40-Design-Additional-Model-Information.md#using-cyclonedx-aiml-properties) - * [Training & testing details](0x40-Design-Additional-Model-Information.md#training--testing-details) - * [Intended use & ethics](0x40-Design-Additional-Model-Information.md#intended-use--ethics) + * [Users & use cases](0x24-Design-Model-Card-Considerations.md#users--use-cases) + * [Technical limitations](0x24-Design-Model-Card-Considerations.md#technical-limitations) + * [Performance tradeoffs](0x24-Design-Model-Card-Considerations.md#performance-tradeoffs) + * [Fairness assessments](0x24-Design-Model-Card-Considerations.md#fairness-assessments) + * [Ethical considerations](0x24-Design-Model-Card-Considerations.md#ethical-considerations) + * [Environmental impact consideration](0x24-Design-Model-Card-Considerations.md#environmental-considerations) + * [Energy consumptions](0x24-Design-Model-Card-Considerations.md#energy-consumptions) + +* [Additional model-related information](0x40-Design-Additional-Model-Information.md#additional-model-related-information) + * [Using CycloneDX AI/ML properties](0x40-Design-Additional-Model-Information.md#using-cyclonedx-aiml-properties) + * [Tokenizers and prompt templates](0x40-Design-Additional-Model-Information.md#tokenizers-and-prompt-templates) + * [Including manufacturing information for the ML model](0x40-Design-Additional-Model-Information.md#including-manufacturing-information-for-the-ml-model) #### Design notes diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index a10bb43..f1163a1 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -388,7 +388,7 @@ The JSON below shows how a few of the [Qwen/Qwen-7B](https://huggingface.co/Qwen } ``` -###### Discussion of model card properties +###### Field notes The model card from above contains the following `cdx:ai-ml:model` properties: From c889e50d534fca07f8a8fb3e4be96bb4a5c6298d Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 11:44:39 -0600 Subject: [PATCH 091/111] Final edits, cleanup, link validation, etc. Signed-off-by: Matt Rutkowski --- Attestations/en/0x10-Introduction.md | 2 +- ML-BOM/en/0x21-Design-Model-Card-Overview.md | 3 ++- ...x23-Design-Model-Card-Quantitative-Analysis.md | 15 +++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Attestations/en/0x10-Introduction.md b/Attestations/en/0x10-Introduction.md index 2790b15..7106351 100644 --- a/Attestations/en/0x10-Introduction.md +++ b/Attestations/en/0x10-Introduction.md @@ -38,7 +38,7 @@ We believe: CycloneDX Attestations provides a non-repudiatable way to communicate compliance to standards. It is intended to be used in a variety of use cases, including: * **Standard authorities**: Authors of security standards that want to create a machine-readable version of their requirements. For example, CycloneDX may be used to represent the requirements of the U.S. Cybersecurity Infrastructure Security Agency's [CISA Secure Software Attestation Form](https://www.cisa.gov/secure-software-attestation-form) for federal agencies or information required by the [EU Artificial Intelligence (AI) Act](https://artificialintelligenceact.eu/). -* **Providers in highly regulated verticals**: Adherence to existing regulatory and industry compliance requirements like [PCI DSS](https://www.pcisecuritystandards.org/standards/pci-dss/), [HIPAA](https://www.hhs.gov/hipaa/index.html), [NIST](https://www.nist.gov/), etc. CycloneDX can be used to provide non-repudiatable evidence of compliance. +* **Providers in highly regulated verticals**: Adherence to existing regulatory and industry compliance requirements like [PCI DSS](https://www.pcisecuritystandards.org/standards/pci-dss/), [HIPAA](https://www.hhs.gov/hipaa/index.html), [NIST](https://www.nist.gov/), etc.; CycloneDX can be used to provide non-repudiatable evidence of compliance. * **Providers building customer trust**: Providers who wish to demonstrate compliance with a specific security standard and/or adherence to a specific security standard via references, evidence and other information provided within BOMs. * **Governance, Risk, and Compliance (GRC) teams**: GRC teams who want to use CycloneDX to assess adherence to their policies, security standards and requirements as well as supporting the automation of compliance processes. * **Engineering teams** - Engineering teams who collect and manage evidence of compliance with internal security standards using CycloneDX BOMs. diff --git a/ML-BOM/en/0x21-Design-Model-Card-Overview.md b/ML-BOM/en/0x21-Design-Model-Card-Overview.md index 5002504..8289187 100644 --- a/ML-BOM/en/0x21-Design-Model-Card-Overview.md +++ b/ML-BOM/en/0x21-Design-Model-Card-Overview.md @@ -2,7 +2,7 @@ ## Model card -A model card describes the intended uses of a machine learning model and potential limitations, including biases and ethical considerations. Model cards typically contain the training parameters, which datasets were used to train the model, performance metrics, and other relevant data useful for ML transparency. This object **SHOULD** be specified for any component of type machine-learning-model and must not be specified for other component types. +A model card describes the intended uses of a machine learning model and potential limitations, including biases and ethical considerations. Model cards typically contain the training parameters, which datasets were used to train the model, performance metrics, and other relevant data useful for ML transparency. This object *SHOULD* be specified for any component of type machine-learning-model and must not be specified for other component types. Throughout the model card sections of this guide, we will show how to use the existing schema to encode information seen in model cards from a more current and robust perspective. @@ -24,6 +24,7 @@ For convenience, here are links to the specific sections for each of those infor * [Configuration parameters & hyperparameters](0x22-Design-Model-Card-Parameters.md#configuration-parameters--hyperparameters) * [Quantitative analysis](0x23-Design-Model-Card-Quantitative-Analysis.md#quantitative-analysis) + * [Benchmarks](0x23-Design-Model-Card-Quantitative-Analysis.md#benchmarks) * [Metrics](0x23-Design-Model-Card-Quantitative-Analysis.md#metrics) * [Performance metrics](0x23-Design-Model-Card-Quantitative-Analysis.md#performance-metrics) * [Graphics](0x23-Design-Model-Card-Quantitative-Analysis.md#graphics) diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 3349eb0..8089dcf 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -6,7 +6,8 @@ This section will feature guidance on filling out information in the Cyclone model card's `quantitativeAnalysis` object and its subcomponents including: -* [Performance metrics](#performance-metrics) +* [Metrics](#metrics) + * [Performance metrics](#performance-metrics) * [Graphics](#graphics) --- @@ -30,12 +31,11 @@ Quantitative analysis is the process of using metrics on benchmarks to determine Benchmarks are standardized test datasets, scenarios, or tasks that define the "playing field". They provide a consistent environment for evaluating different models and enable the comparison of their metrics across similar models. -##### Types of machine learning benchmarks +#### Types of machine learning benchmarks Benchmarks use standardized datasets to objectively compare model quality, efficiency, fairness, and speed, providing a shared baseline for identifying areas for improvement in various categories. -* **[Large Language Models (LLM)](0x90-Appendix-A_Glossary.md#large-language-model-llm)** and **[Natural Language Processing (NLP)](0x90-Appendix-A_Glossary.md#natural-language-processing-nlp)** (e.g., speech recognition or text classification) - These benchmarks evaluate reasoning, knowledge, and generation capabilities. -
A few examples of datasets used to benchmark these models include: +* [Large Language Models (LLM)](0x90-Appendix-A_Glossary.md#large-language-model-llm) and [Natural Language Processing (NLP)](0x90-Appendix-A_Glossary.md#natural-language-processing-nlp) (e.g., speech recognition or text classification) - These benchmarks evaluate reasoning, knowledge, and generation capabilities. A few examples of datasets used to benchmark these models against different tasks include: * *General Tasks* * [MMLU](https://huggingface.co/datasets/cais/mmlu), [MMLU-Pro](https://huggingface.co/datasets/TIGER-Lab/MMLU-Pro) (Massive Multitask Language Understanding): Tests knowledge across STEM, humanities, and social sciences. @@ -54,8 +54,7 @@ Benchmarks use standardized datasets to objectively compare model quality, effic * *Other Tasks* * [IMDB](https://www.kaggle.com/datasets/lakshmi25npathi/imdb-dataset-of-50k-movie-reviews): a large dataset of 50K, highly polarized, movie reviews for NLP sentiment analysis and classification.
-* **[Computer Vision](0x90-Appendix-A_Glossary.md#computer-vision)** (e.g., digital image or video recognition) -These benchmarks measure the performance, accuracy, and efficiency of models in tasks like image classification, object detection, segmentation, and tracking.

Some example datasets: +* [Computer Vision](0x90-Appendix-A_Glossary.md#computer-vision) (e.g., digital image or video recognition) - These benchmarks measure the performance, accuracy, and efficiency of models in tasks like image classification, object detection, segmentation, and tracking. Some example "vision" datasets include: * [ImageNet](image-net.org): large-scale dataset for computer vision, featuring over 14 million annotated, high-resolution images across thousands of object categories organized by the [WordNet](https://en.wikipedia.org/wiki/WordNet) hierarchy. * [MathVista](https://huggingface.co/datasets/AI4Math/MathVista): Used to evaluating math reasoning in Visual Contexts. It consists of three datasets, *IQTest*, *FunctionQA*, and *PaperQA*, which are tailored to evaluate visual reasoning on puzzle test figures, algebraic reasoning over functional plots, and scientific reasoning with academic paper figures, respectively. @@ -71,7 +70,7 @@ AI benchmarking metrics are standardized, quantitative measures used to evaluate > [!Note] Currently, CycloneDX supports declaring metrics relative to *performance benchmarks* which is the most consistently documented metrics described within producer published model cards. -### Performance metrics +#### Performance metrics Performance metrics are specific, quantitative measures used to evaluate a model's behavior, such as accuracy, precision, recall, perplexity, or inference speed. They provide the raw, numerical data for analysis. @@ -149,7 +148,7 @@ This example shows how to provide an [F1 score](https://en.wikipedia.org/wiki/F- --- -#### Graphics +### Graphics Model cards typically include graphs, charts and other graphics that highlight the model's performance benchmarks often relative to other models. This section examples the use of the CycloneDX `graphics` object to include a collection of these graphics in the ML-BOM as part of its quantitative analysis information. From 64f49a5b12318de973bd5f4d801f0d0c482d02c3 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 11:48:48 -0600 Subject: [PATCH 092/111] Final edits, cleanup, link validation, etc. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x70-Use_Case_Software_Simple.md | 3 --- .../0x85-Appendix-1-Complete-Examples.md} | 0 2 files changed, 3 deletions(-) delete mode 100644 ML-BOM/en/0x70-Use_Case_Software_Simple.md rename ML-BOM/en/{0x85-Appendix-1-Examples.md => draft/0x85-Appendix-1-Complete-Examples.md} (100%) diff --git a/ML-BOM/en/0x70-Use_Case_Software_Simple.md b/ML-BOM/en/0x70-Use_Case_Software_Simple.md deleted file mode 100644 index 6a61dab..0000000 --- a/ML-BOM/en/0x70-Use_Case_Software_Simple.md +++ /dev/null @@ -1,3 +0,0 @@ -## Use Cases: TBD - - diff --git a/ML-BOM/en/0x85-Appendix-1-Examples.md b/ML-BOM/en/draft/0x85-Appendix-1-Complete-Examples.md similarity index 100% rename from ML-BOM/en/0x85-Appendix-1-Examples.md rename to ML-BOM/en/draft/0x85-Appendix-1-Complete-Examples.md From 035e7d2b50329f806f74412c4e21e80f33b5111a Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 11:52:53 -0600 Subject: [PATCH 093/111] Final edits, cleanup, link validation, etc. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x01-Frontispiece.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/ML-BOM/en/0x01-Frontispiece.md b/ML-BOM/en/0x01-Frontispiece.md index 9ef301a..9f19fdb 100644 --- a/ML-BOM/en/0x01-Frontispiece.md +++ b/ML-BOM/en/0x01-Frontispiece.md @@ -6,25 +6,21 @@ ## About the Guide CycloneDX is a modern standard for the software supply chain. It has been ratified as [ECMA-424](https://ecma-international.org/publications-and-standards/standards/ecma-424/) by Ecma International. -The content in this guide results from continuous community feedback and input from leading experts in the software -supply chain security field. This guide would not be possible without valuable feedback from the CycloneDX Industry -Working Group (IWG), the CycloneDX Core Working Group (CWG), the many CycloneDX Feature Working Groups (FWG), -Ecma International Technical Committee 54, and a global network of contributors and supporters. +The content in this guide results from work of the CycloneDX AI/ML WoWork Group with continuous community feedback and input from leading experts in the field. This guide would not be possible without valuable feedback from peers at the CycloneDX Industry Working Group (IWG), the CycloneDX Core Working Group (CWG), the many CycloneDX Feature Working Groups (FWG), Ecma International Technical Committee 54, and a global network of contributors and supporters. ## Copyright and License ![license](../../images/license.svg) -Copyright © 2025 The OWASP Foundation. +Copyright © 2026 The OWASP Foundation. -This document is released under the [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/). -For any reuse or distribution, you must make clear to others the license terms of this work. +This document is released under the [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/). For any reuse or distribution, you must make clear to others the license terms of this work.
\emptyparagraph
-First Edition, 00 Month 2025 +First Edition, 05 February 2026
\emptyparagraph @@ -32,7 +28,7 @@ First Edition, 00 Month 2025 | Version | Changes | Updated On | Updated By | |----------------|----------------------------|------------|------------------------------| -| First Edition | Initial Release | 2025-xx-xx | CycloneDX Core Working Group | +| First Edition | Initial Release | 2026-02-05 | CycloneDX AI/ML Working Group |
\newpage From 79fc61785513aa38926cc628b80535759cc54968 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 12:03:08 -0600 Subject: [PATCH 094/111] Final edits, cleanup, link validation, etc. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x02-Preface.md | 23 +- .../en/images/ml-bom-metadata-component.svg | 651 +++++++++++++++++- 2 files changed, 656 insertions(+), 18 deletions(-) diff --git a/ML-BOM/en/0x02-Preface.md b/ML-BOM/en/0x02-Preface.md index 2599720..b0aff28 100644 --- a/ML-BOM/en/0x02-Preface.md +++ b/ML-BOM/en/0x02-Preface.md @@ -1,29 +1,18 @@ # Preface -Welcome to the Authoritative Guide series by the OWASP Foundation and OWASP CycloneDX. In this series, we aim to -provide comprehensive insights and practical guidance, ensuring that security professionals, developers, and -organizations alike have access to the latest best practices and methodologies. +Welcome to the Authoritative Guide series by the OWASP Foundation and OWASP CycloneDX. In this series, we aim to provide comprehensive insights and ractical guidance, ensuring that security professionals, developers, and organizations alike have access to the latest best practices and methodologies. -At the heart of the OWASP Foundation lies a commitment to inclusivity and openness. We firmly believe that everyone -deserves a seat at the table when it comes to shaping the future of cybersecurity standards. Our collaborative -model fosters an environment where diverse perspectives converge to drive innovation and excellence. +At the heart of the OWASP Foundation lies a commitment to inclusivity and openness. We firmly believe that everyone deserves a seat at the table when it comes to shaping the future of cybersecurity standards. Our collaborative model fosters an environment where diverse perspectives converge to drive innovation and excellence. -In line with this ethos, the OWASP Foundation has partnered with Ecma International to create an inclusive, -community-driven ecosystem for security standards development. This collaboration empowers individuals to contribute -their expertise and insights, ensuring that standards like CycloneDX reflect the collective wisdom of the global -cybersecurity community. +In line with this ethos, the OWASP Foundation has partnered with Ecma International to create an inclusive, community-driven ecosystem for security standards development. This collaboration empowers individuals to contribute their expertise and insights, ensuring that standards like CycloneDX reflect the collective wisdom of the global cybersecurity community. -One standout example of this model is OWASP CycloneDX, which has been ratified as an Ecma International standard and is -now known as ECMA-424. By leveraging the strengths of both organizations, CycloneDX serves as a cornerstone of security -best practices, providing organizations with a universal standard for software and system transparency. +One standout example of this model is OWASP CycloneDX, which has been ratified as an Ecma International standard and is now known as ECMA-424. By leveraging the strengths of both organizations, CycloneDX serves as a cornerstone of security best practices, providing organizations with a universal standard for software and system transparency. -As you embark on your journey through this Authoritative Guide, we encourage you to engage actively with the content -and join us in shaping the future of cybersecurity standards. Together, we can build a safer and more resilient digital -world for all. +As you embark on your journey through this Authoritative Guide, we encourage you to engage actively with the content and join us in shaping the future of cybersecurity standards. Together, we can build a safer and more resilient digital world for all. --- -Andrew van der Stock +Andrew van der Stock Executive Director, OWASP Foundation
diff --git a/ML-BOM/en/images/ml-bom-metadata-component.svg b/ML-BOM/en/images/ml-bom-metadata-component.svg index 1e74019..0ee0321 100644 --- a/ML-BOM/en/images/ml-bom-metadata-component.svg +++ b/ML-BOM/en/images/ml-bom-metadata-component.svg @@ -1 +1,650 @@ -metadata: object+component: <component>+...<bom>: object+metadata: <metadata>+...component: object+bom-ref: "pkg:huggingface/Qwen/Qwen-7B@ef3c..."+type: "machine-learning-model"+... \ No newline at end of file + +metadata: object+component: <component>+...<bom>: object+metadata: <metadata>+...component: object+bom-ref: "pkg:huggingface/Qwen/Qwen-7B@ef3c..."+type: "machine-learning-model"+... From 01f5649d4875daab836856ad5f67a4773f7baa13 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 12:12:31 -0600 Subject: [PATCH 095/111] Final edits, cleanup, link validation, etc. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 3f7853c..65d5906 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -13,6 +13,7 @@ The [Core Concepts](0x15-Core-Concepts.md#key-components-of-an-ml-bom) listed in For convenience, here are links to the specific sections for each of those informational areas: * [Anatomy of an ML-BOM](#anatomy-of-an-ml-bom) +* [Declaring ML Models](#declaring-ml-models) * [Describing models as components](#describing-models-as-components) * [Model repositories as components](#model-repositories-as-components) * [Model identifiers](#model-identifiers) @@ -29,7 +30,7 @@ In CycloneDX, a model is considered a `component` where general best practices f --- -## Model Component +## Declaring ML models ### Describing models as components @@ -38,7 +39,9 @@ A model should always be declared as a CycloneDX `component`. If the model itse The object model's pseudo-schema would look something like this: ![](images/ml-bom-metadata-component.svg) -##### Example: JSON equivalent +###### Example: Declaring an ML model in an ML-BOM + +The CycloneDX JSON pseudocode below shows how an ML model would be declared as the "subject" `component` of an ML-BOM within the top-level `metadata`: ```json { @@ -63,10 +66,12 @@ The object model's pseudo-schema would look something like this: } ``` -###### Discussion of fields +###### Field notes * **bom-ref** - Please note the `bom-ref` value includes the first seven characters of the larger hash value from the `purl` component identifier which is sufficient for local identification within the BOM itself. +--- + #### Model repositories as components When referencing an ML model as a component, it typically means you are referencing a **model repository** comprised of metadata and a set of files (e.g., pre-trained tensor data in various formats, model configurations, tokenizers, tokenizer configurations, prompt templates, Python code, etc.) which would be selectively used with various, compatible AI or ML applications and frameworks. From 55eccfde8871309c4f837df77bcb3c5438cc93f3 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 12:16:03 -0600 Subject: [PATCH 096/111] Final edits, cleanup, link validation, etc. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 65d5906..25d7cde 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -369,6 +369,10 @@ It is important to capture any of these transformations as the model's lineage o } ``` +###### Field notes + +* **ancestors** - `ancestors` entries are themselves CycloneDX `component` objects. It should be noted that these models may have their own ML-BOMs which could be located via their identifiers (e.g., `purl`) or by providing `externalReferences` for readers to follow. + * **Note**: If at the time an ML-BOM is created for a model its downstream model variants (e.g., finetunings, quantizations, etc. derived from the model) are known, these can also be recorded within the `pedigree` object as `descendants`.
From 011e4e8473eb53c137e9799979bc06823ab7a98e Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 12:17:32 -0600 Subject: [PATCH 097/111] Final edits, cleanup, link validation, etc. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 25d7cde..ceebc3d 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -373,7 +373,9 @@ It is important to capture any of these transformations as the model's lineage o * **ancestors** - `ancestors` entries are themselves CycloneDX `component` objects. It should be noted that these models may have their own ML-BOMs which could be located via their identifiers (e.g., `purl`) or by providing `externalReferences` for readers to follow. -* **Note**: If at the time an ML-BOM is created for a model its downstream model variants (e.g., finetunings, quantizations, etc. derived from the model) are known, these can also be recorded within the `pedigree` object as `descendants`. +##### Declaring known descendents + +If at the time an ML-BOM is created for a model its downstream model variants (e.g., finetunings, quantizations, etc. derived from the model) are known, these can also be recorded within the `pedigree` object as `descendants`.
\newpage From cd8dee2d0d92a57f10a39ee4ced44583b68d6ca1 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 12:17:59 -0600 Subject: [PATCH 098/111] Final edits, cleanup, link validation, etc. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index ceebc3d..96dec9f 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -375,7 +375,7 @@ It is important to capture any of these transformations as the model's lineage o ##### Declaring known descendents -If at the time an ML-BOM is created for a model its downstream model variants (e.g., finetunings, quantizations, etc. derived from the model) are known, these can also be recorded within the `pedigree` object as `descendants`. +If at the time an ML-BOM is created for a model its downstream model variants (e.g., finetunings, quantizations, etc. derived from the model) are known, these can also be recorded within the `pedigree` object as `descendants` in a similar manner.
\newpage From 9c87e0505ffdfad7df64211ca226224e86b1ae7d Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 5 Feb 2026 12:31:10 -0600 Subject: [PATCH 099/111] Final edits, cleanup, link validation, etc. Signed-off-by: Matt Rutkowski --- .../0x20-Design-Model-Component-Metadata.md | 10 +++--- .../en/0x22-Design-Model-Card-Parameters.md | 33 ++++++++--------- ...Design-Model-Card-Quantitative-Analysis.md | 26 +++++++------- .../0x24-Design-Model-Card-Considerations.md | 36 +++++++++---------- ...x40-Design-Additional-Model-Information.md | 10 +++--- 5 files changed, 56 insertions(+), 59 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 96dec9f..b429698 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -66,7 +66,7 @@ The CycloneDX JSON pseudocode below shows how an ML model would be declared as t } ``` -###### Field notes +###### Field discussion * **bom-ref** - Please note the `bom-ref` value includes the first seven characters of the larger hash value from the `purl` component identifier which is sufficient for local identification within the BOM itself. @@ -120,7 +120,7 @@ Since the the model repository is hosted in Hugging Face Hub, the [Huggingface p ``` -###### Discussion of model fields and metadata +###### Field discussion This section provides best practice guidance on how the component fields were filled out for this example. @@ -216,7 +216,7 @@ Each can be specifically identified in a CycloneDX component using a Package URL } ``` -###### Field notes +###### Field discussion * **type** - the type has the value `machine-learning-model` since the single file contains all the information (e.g., default configuration parameters, references to architectures and tokenizers, prompt template, etc.) needed to run the model in GGUF inference frameworks. @@ -330,7 +330,7 @@ then the model component's new hierarchy of composing files would be described a ML models are often derived from existing, pre-trained models to optimize performance, reduce resource consumption, and adapt to specialized tasks without training from scratch. Some reasons for this include: -* **Fine-Tuning:**: Specialized adaptation where a general model (e.g., LLM) is retrained on a smaller, targeted dataset to improve performance for specific domains. +* **Fine-Tuning**: Specialized adaptation where a general model (e.g., LLM) is retrained on a smaller, targeted dataset to improve performance for specific domains. * **Quantization**: Reduces model size and increases inference speed by mapping parameters to lower-precision tensor formats (e.g., from [`FP32`](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) to `int8` or `Q4_K_M` precision), which also lowers energy consumption for edge devices. * **Format Conversions**: Transforming models between frameworks (e.g., PyTorch to ONNX) ensures interoperability, allowing deployment on different frameworks and accelerators. * **Pruning**: Derives a smaller model by removing redundant or less important parameters (weights) that do not significantly contribute to output accuracy. @@ -369,7 +369,7 @@ It is important to capture any of these transformations as the model's lineage o } ``` -###### Field notes +###### Field discussion * **ancestors** - `ancestors` entries are themselves CycloneDX `component` objects. It should be noted that these models may have their own ML-BOMs which could be located via their identifiers (e.g., `purl`) or by providing `externalReferences` for readers to follow. diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index f1163a1..938905e 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -42,22 +42,20 @@ Please note that links to external documentation that detail the model training Describes the primary task of (or goal) of the machine learning model. Some examples include: -* **Anomaly Detection** - Identifying outliers or unusual patterns in data. -* **Classification** - Categorizing inputs into predefined labels (e.g., spam/not-spam, image recognition). -* **Clustering** - Grouping unlabeled data based on similar characteristics (e.g., customer segmentation). -* **Dimensionality Reduction** - Simplifying complex data by reducing the number of variables while preserving core information. -* **Generation** - Creating new data based upon prompted instructions (e.g., Large Language Models (LLMs), image or audio diffusion models, etc.). -* **Recommendation/Association** - Finding relationships between items (e.g., "users who bought this also bought..."). -* **Regression** - Predicting continuous numerical values (e.g., house prices, temperature forecasting). +* **Anomaly Detection**: Identifying outliers or unusual patterns in data. +* **Classification**: Categorizing inputs into predefined labels (e.g., spam/not-spam, image recognition). +* **Clustering**: Grouping unlabeled data based on similar characteristics (e.g., customer segmentation). +* **Dimensionality Reduction**: Simplifying complex data by reducing the number of variables while preserving core information. +* **Generation**: Creating new data based upon prompted instructions (e.g., Large Language Models (LLMs), image or audio diffusion models, etc.). +* **Recommendation/Association**: Finding relationships between items (e.g., "users who bought this also bought..."). +* **Regression**: Predicting continuous numerical values (e.g., house prices, temperature forecasting). #### Architecture family -The model architecture family th - -such as a Transformer network, Convolutional Neural Network (CNN), residual neural network (RNN), LSTM neural network, etc. - An architecture family defines the structural and data processing methodology of the model's neural network. It does not typically describe a single model, but rather describes the general design of the neural network (NN), mathematical approach, context and attention mechanisms and the like. It should provide insight to those versed in the field as how the model general is constructed. +The model architecture family field should include descriptive names of neural network architectures which would be recognizable to those in the field of Machine Learning (ML). + Some examples of commonly referenced neural network (NN) architecture families include: * **Transformers** - an architecture designed to process sequential data (like text, speech, or images) in parallel rather than in order. @@ -75,11 +73,10 @@ The model architecture field is intended to include specific keywords to identif These are typically found in one of several locations relative to the model: -* **Model Card** - the associated "model card" (e.g., `README.md` in Hugging Face) may contain a mentions of specific class names like `LlamaForCausalLM`, `BertModel`, or `VisionTransformer`. -* **Framework-Specific Implementation Keywords** or tags - -Depending on your code environment (PyTorch, TensorFlow, llama.cpp, etc.) that identify specific model code within the platform or environment. -* **Framework-Specific Configuration files** (e.g., Hugging Face transformer's `config.json` file) - may contain the name of the class or function used to configure the framework for the specific implementation recommended for the associated model. -* **Academic Research Papers** (e.g., arXiv) - may include detailed descriptors of processing algorithms, supported training or inference engines or specific, named implementations +* **Model Card**: the associated "model card" (e.g., `README.md` in Hugging Face) may contain a mentions of specific class names like `LlamaForCausalLM`, `BertModel`, or `VisionTransformer`. +* **Framework-Specific Implementation Keywords** or tags: Depending on your code environment (PyTorch, TensorFlow, llama.cpp, etc.) that identify specific model code within the platform or environment. +* **Framework-Specific Configuration files** (e.g., Hugging Face transformer's `config.json` file): may contain the name of the class or function used to configure the framework for the specific implementation recommended for the associated model. +* **Academic Research Papers** (e.g., arXiv): may include detailed descriptors of processing algorithms, supported training or inference engines or specific, named implementations ###### Example: Model card metadata for the Qwen-7B model @@ -225,7 +222,7 @@ back dataset", } ``` -###### Field notes +###### Field discussion * **url** - Please note that URLs may be to either public or private resources. For example, in the case of the ACME `private` dataset above, the URL is likely behind an Access Control Point (ACP) which regulates traffic to the private resource in accordance with the ACME company's governance policies. @@ -388,7 +385,7 @@ The JSON below shows how a few of the [Qwen/Qwen-7B](https://huggingface.co/Qwen } ``` -###### Field notes +###### Field discussion The model card from above contains the following `cdx:ai-ml:model` properties: diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 8089dcf..9cf1184 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -35,30 +35,30 @@ Benchmarks are standardized test datasets, scenarios, or tasks that define the Benchmarks use standardized datasets to objectively compare model quality, efficiency, fairness, and speed, providing a shared baseline for identifying areas for improvement in various categories. -* [Large Language Models (LLM)](0x90-Appendix-A_Glossary.md#large-language-model-llm) and [Natural Language Processing (NLP)](0x90-Appendix-A_Glossary.md#natural-language-processing-nlp) (e.g., speech recognition or text classification) - These benchmarks evaluate reasoning, knowledge, and generation capabilities. A few examples of datasets used to benchmark these models against different tasks include: +* [Large Language Models (LLM)](0x90-Appendix-A_Glossary.md#large-language-model-llm) and [Natural Language Processing (NLP)](0x90-Appendix-A_Glossary.md#natural-language-processing-nlp) (e.g., speech recognition or text classification): These benchmarks evaluate reasoning, knowledge, and generation capabilities. A few examples of datasets used to benchmark these models against different tasks include: - * *General Tasks* + * **General Tasks** * [MMLU](https://huggingface.co/datasets/cais/mmlu), [MMLU-Pro](https://huggingface.co/datasets/TIGER-Lab/MMLU-Pro) (Massive Multitask Language Understanding): Tests knowledge across STEM, humanities, and social sciences. * [HellaSwag](https://huggingface.co/datasets/Rowan/hellaswag) / [WinoGrande](https://huggingface.co/datasets/allenai/winogrande): Common sense reasoning and pronoun resolution tasks. * [GLUE](https://gluebenchmark.com/): benchmarking resources for training, evaluating, and analyzing natural language understanding systems. GLUE's dataset is available in Hugging Face Hub ([nyu-mll/glue](https://huggingface.co/datasets/nyu-mll/glue)) and supports multiple tasks that can be evaluated independently, for example: * *ax* - evaluates sentence understanding through Natural Language Inference (NLI) problems. * *cola* - The Corpus of Linguistic Acceptability consists of English acceptability judgments drawn from books and journal articles on linguistic theory. * *mnli* - The Multi-Genre Natural Language Inference Corpus consists of sentence pairs with textual entailment annotations. Given a premise sentence and a hypothesis sentence, the task is to predict whether the premise entails the hypothesis. - * *Math/STEM tasks* + * **Math/STEM tasks** * [GSM8K](https://huggingface.co/datasets/openai/gsm8k) (OpenAII, Grade School Math 8K): a dataset of 8.5K high quality linguistically diverse grade school math word problems. * [MATH-500](https://huggingface.co/datasets/HuggingFaceH4/MATH-500) (Hugging Face): Benchmarks specifically designed to evaluate mathematical reasoning. - * *Coding Tasks* + * **Coding Tasks** * [HumanEval](https://huggingface.co/datasets/openai/openai_humaneval) (OpenAI): used to evaluate the functional correctness of code generated LLMs. It consists of hand-crafted programming problems designed to test reasoning and code synthesis abilities. * [MBPP](https://huggingface.co/datasets/Muennighoff/mbpp) (Mostly Basic Python Problems ): Benchmarks for evaluating code generation and programming capabilities. * [CodeXGLUE](https://github.com/microsoft/CodeXGLUE/tree/main/Code-Code/code-refinement) (MicroSoft, Code Refinement): Used to evaluate a model's ability to remove (i.e., "fix") bugs from Java code (i.e., refine the code) with accuracy being reported as [BLEU](https://learn.microsoft.com/en-us/azure/ai-services/translator/custom-translator/concepts/bleu-score) scores. - * *Other Tasks* + * **Other Tasks** * [IMDB](https://www.kaggle.com/datasets/lakshmi25npathi/imdb-dataset-of-50k-movie-reviews): a large dataset of 50K, highly polarized, movie reviews for NLP sentiment analysis and classification.
-* [Computer Vision](0x90-Appendix-A_Glossary.md#computer-vision) (e.g., digital image or video recognition) - These benchmarks measure the performance, accuracy, and efficiency of models in tasks like image classification, object detection, segmentation, and tracking. Some example "vision" datasets include: +* [Computer Vision](0x90-Appendix-A_Glossary.md#computer-vision) (e.g., digital image or video recognition): These benchmarks measure the performance, accuracy, and efficiency of models in tasks like image classification, object detection, segmentation, and tracking. Some example "vision" datasets include: * [ImageNet](image-net.org): large-scale dataset for computer vision, featuring over 14 million annotated, high-resolution images across thousands of object categories organized by the [WordNet](https://en.wikipedia.org/wiki/WordNet) hierarchy. * [MathVista](https://huggingface.co/datasets/AI4Math/MathVista): Used to evaluating math reasoning in Visual Contexts. It consists of three datasets, *IQTest*, *FunctionQA*, and *PaperQA*, which are tailored to evaluate visual reasoning on puzzle test figures, algebraic reasoning over functional plots, and scientific reasoning with academic paper figures, respectively. - * [MNIST](https://www.tensorflow.org/datasets/catalog/mnist) (Modified National Institute of Standards and Technology database) (link to the Tensorflow/Keras catalog): a large database of handwritten digits (glyphs) that is commonly used for training various image processing systems. + * [MNIST](https://www.tensorflow.org/datasets/catalog/mnist) (Modified National Institute of Standards and Technology database): a large database of handwritten digits (glyphs) that is commonly used for training various image processing systems. Again, the list above contains just a small number of examples of benchmarking datasets that can be used to train and evaluate models. @@ -76,9 +76,9 @@ Performance metrics are specific, quantitative measures used to evaluate a model ##### Common Performance Metrics -* **Accuracy** - Overall correctness; typically represented as a percentage of correct responses to the full set of problems posed by a benchmark's dataset. -* **Precision** - Of predicted positives, how many are correct. -* **Recall** (Sensitivity) - Of actual positives, how many are found. +* **Accuracy**: Overall correctness; typically represented as a percentage of correct responses to the full set of problems posed by a benchmark's dataset. +* **Precision**: Of predicted positives, how many are correct. +* **Recall** (Sensitivity): Of actual positives, how many are found. * **F1 Score**: Harmonic mean of *Precision* and *Recall*. -#### The value of quantitative analysis +### The value of quantitative analysis * **Numerical Metrics**: Provides measurable data (e.g., error rates, latency, performance scores) rather than subjective feedback. * **Objective Evaluation**: Provides reproducible, scalable results that can be compared across different models or versions. @@ -27,11 +25,11 @@ Quantitative analysis is the process of using metrics on benchmarks to determine --- -### Benchmarks +## Benchmarks Benchmarks are standardized test datasets, scenarios, or tasks that define the "playing field". They provide a consistent environment for evaluating different models and enable the comparison of their metrics across similar models. -#### Types of machine learning benchmarks +### Types of machine learning benchmarks Benchmarks use standardized datasets to objectively compare model quality, efficiency, fairness, and speed, providing a shared baseline for identifying areas for improvement in various categories. @@ -64,7 +62,7 @@ Again, the list above contains just a small number of examples of benchmarking d --- -### Metrics +## Metrics AI benchmarking metrics are standardized, quantitative measures used to evaluate and compare the performance, accuracy, efficiency, and reliability of artificial intelligence models against established, uniform tasks and datasets. They function as a gauge progress in capabilities like reasoning, coding, and language understanding to provide simple comparisons to similar models. @@ -148,7 +146,7 @@ This example shows how to provide an [F1 score](https://en.wikipedia.org/wiki/F- --- -### Graphics +## Graphics Model cards typically include graphs, charts and other graphics that highlight the model's performance benchmarks often relative to other models. This section examples the use of the CycloneDX `graphics` object to include a collection of these graphics in the ML-BOM as part of its quantitative analysis information. diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 4b19230..99469c2 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -1,10 +1,8 @@ -# ML-BOM Design and Best Practices - -## Considerations +# Model Design Considerations ![](images/ml-anatomy-model-card-considerations.svg) -This section will feature guidance on filling out information in the Cyclone model card's `considerations` object and its subcomponents including: +This section will feature guidance on filling out information in the Cyclone model card's design `considerations` object and its subcomponents including: * [Users](#users) - Who are the intended users of the model? * [Use cases](#use-cases)- What are the intended use cases for the model inclusive of the Operational Design Domains (ODD)? @@ -16,7 +14,7 @@ This section will feature guidance on filling out information in the Cyclone mod --- -### Users & use cases +## Users & use cases Used to provide list describing the intended users of the model along with a list of envisioned use cases for the model. @@ -61,7 +59,7 @@ This example shows a list for what kind of user and use case information would b --- -### Technical limitations +## Technical limitations Since ML models are fundamentally probabilistic and operate on pattern recognition from the data they are trained on, they are prone to various technical limitations. @@ -100,7 +98,7 @@ This example shows a list for what kind of technical limitations might be associ --- -### Performance Tradeoffs +## Performance Tradeoffs When creating Machine Learning (ML) models, developers must navigate several core performance tradeoffs to align model capabilities with business needs and technical constraints. @@ -140,7 +138,7 @@ This example how to provide performance tradeoffs against a few that have been a --- -### Ethical considerations +## Ethical considerations Used to provide list describing known ethical considerations when using a model. Each consideration is an object containing two fields: @@ -195,7 +193,7 @@ Based on technical reports and safety evaluations such as Qwen3Guard, the follow --- -### Fairness assessments +## Fairness assessments Fairness assessments convey information about the benefits and harms of the model to an identified at risk group. They involve measuring how models treat different social groups to ensure they do not perpetuate or amplify harmful social biases. @@ -244,9 +242,9 @@ This example shows how fairness assessment information would be included in a a --- -### Environmental considerations +## Environmental considerations -#### Energy consumptions +### Energy consumptions This section describes how model providers can publish the energy costs incurred during different stages of the model's lifecycle in order to address potential governmental regulations and requirements. This information includes the energy sources (i.e., for the datacenters) as well as disclosure of CO2 emission cost equivalents and CO2 offsets (credits). diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 61d0b12..2774cd6 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -1,6 +1,4 @@ -# ML-BOM Design and Best Practices - -## Additional model-related information +# Additional model-related information This section describes the design and best practices when providing other model-related information an ML model's component and model card within a CycloneDX ML-BOM. @@ -19,11 +17,13 @@ For convenience, here are links to the specific sections for some of these ackno --- -### Using CycloneDX AI/ML properties +## Using CycloneDX AI/ML properties This section includes discussion and examples of supported AI/ML-related metadata properties that may be used to classify models as part of their model card information. This method utilizes reserved [AI/ML property names](https://github.com/CycloneDX/cyclonedx-property-taxonomy/cdx/ai-ml.md) registered under the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy). -#### Annotating a model's supported languages +--- + +## Annotating a model's supported languages Models are can be trained in one or more languages (i.e., multilingual models). @@ -54,7 +54,7 @@ Models are can be trained in one or more languages (i.e., multilingual models). --- -#### Providing free-form tags for search +## Providing free-form tags for search This section describes how to "tag" model components with non-standard keywords and terms seen in various model catalogs or repositories for search or "lookup" purposes. @@ -82,7 +82,7 @@ This section describes how to "tag" model components with non-standard keywords --- -### Tokenizers and prompt templates +## Tokenizers and prompt templates Tokenizers provide the preprocessing (encoding) and postprocessing (decoding) functions to convert input and output information to tokens that the associated ML model was trained on and used for inference. @@ -163,7 +163,7 @@ For the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model, the chat temp --- -### Including manufacturing information for the ML model +## Including manufacturing information for the ML model This section shows how "manufacturing" (i.e., "training") information is provided relative to the model described by an ML-BOM. @@ -244,8 +244,7 @@ First, create entries for all the "components" used in the training process as p * **components** - The components listed to "train" the model shown above would also include "data" type components as described in the previous section "[Declaring datasets](0x22-Design-Model-Card-Parameters.md#declaring-datasets)". - -#### Providing training workflow details +### Providing training workflow details After the hardware and software "stack" of training components have been declared under the `formulation` object, a CycloneDX `workflow` object, with the details of the training tasks as `task` objects (inclusive of all relevant inputs, outputs, steps, etc.), can then be declared: @@ -273,7 +272,7 @@ After the hardware and software "stack" of training components have been declare } ``` -#### Declaring the runtime topology +### Declaring the runtime topology Lastly, you would describe the component "stack" as a graph of `runtimeTopology` dependencies for the workflow above. In this case, the training was done using an OCI (Open Container Initiative) standard container image which "provide" a declared set of component libraries (pre-installed on the image): From b3afcd15484c6230ce069bd5df34f3f787a2056c Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 19 Feb 2026 14:52:17 -0600 Subject: [PATCH 107/111] Attempt to fix text scaling in svg Signed-off-by: Matt Rutkowski --- .../en/images/ml-bom-metadata-component.svg | 85 ++++++++++--------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/ML-BOM/en/images/ml-bom-metadata-component.svg b/ML-BOM/en/images/ml-bom-metadata-component.svg index 0ee0321..1c1debe 100644 --- a/ML-BOM/en/images/ml-bom-metadata-component.svg +++ b/ML-BOM/en/images/ml-bom-metadata-component.svg @@ -21,16 +21,17 @@ inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" - inkscape:zoom="2.3147502" - inkscape:cx="240.84672" - inkscape:cy="152.93227" + inkscape:zoom="1" + inkscape:cx="240" + inkscape:cy="147" inkscape:window-width="1536" inkscape:window-height="879" inkscape:window-x="86" - inkscape:window-y="108" + inkscape:window-y="33" inkscape:window-maximized="0" - inkscape:current-layer="svg37" - inkscape:document-units="in" />metadatametadata: object: object++component: <component: <componentcomponent>>++......<bom><bom>: object: object++metadata: <metadata: <metadatametadata>>++......componentcomponent: object: object++bombom--ref: "pkg:huggingface/Qwen/Qwenref: "pkg:huggingface/Qwen/Qwen--7B@ef3c..."7B@ef3c..."++type: type: ""machinemachine--learninglearning--modelmodel""++...... Date: Thu, 19 Feb 2026 15:33:50 -0600 Subject: [PATCH 108/111] Fix all invalid markdown callout blocks Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x20-Design-Model-Component-Metadata.md | 2 +- ML-BOM/en/0x22-Design-Model-Card-Parameters.md | 6 ++---- ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md | 2 +- ML-BOM/en/0x24-Design-Model-Card-Considerations.md | 6 ++---- ML-BOM/en/0x40-Design-Additional-Model-Information.md | 2 +- ML-BOM/en/0x91-Appendix-B_References.md | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 2d465db..2104f6a 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -240,7 +240,7 @@ If we look inside the repository for the [Qwen/Qwen-7B model in Huggingface](htt The simplified JSON below shows how to declare a few of the files from the model repository's complete file list under the model's `component` declaration within the BOM's `metadata`. -Note that we use the Package URL syntax to provide the additional path (with the model repository or "package") to each individual file by appending it using the `#` hash symbol as a separator. Also, notice that the commit hash (identifier) varies per-file. +> **Note**: In the JSON below, we use the Package URL (PURL) syntax to provide the additional path (with the model repository or "package") to each individual file by appending it using the `#` hash symbol as a separator. Also, notice that the commit hash (identifier) varies per-file. ```json { diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index 80829e7..fb120fa 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -294,7 +294,7 @@ The public datasets, as documented in the model's research paper include: Describes the input and output data types (formats) of the model. ->[!Note] The current object used to describe model inputs and outputs is limited to describing the data types strictly used for training and inference. Future revisions of CycloneDX plan to expand these objects to provide more detailed information especially in regard to names, formats and defaults for model configuration parameters and hyperparameters. +> **Note**: The current object used to describe model inputs and outputs is limited to describing the data types strictly used for training and inference. Future revisions of CycloneDX plan to expand these objects to provide more detailed information especially in regard to names, formats and defaults for model configuration parameters and hyperparameters. In order to provide information on model parameters and hyperparameters using existing CycloneDX schema, it is recommended best practice as shown in the next section "[Declaring other properties](#declaring-other-properties)" and its "[Example: Model parameters & hyperparameters for the Qwen-7B model](#example-model-parameters--hyperparameters-for-the-qwen-7b-model)". @@ -331,7 +331,7 @@ In order to provide information on model parameters and hyperparameters using ex In general, model configuration parameters describe values that are directly used to configure model processing applications and frameworks and their implementations of model architectures. For example, most models that appear in Hugging Face typically include configuration files for both the models and the tokenizers they are designed for use with the [Hugging Face Transformers](https://huggingface.co/docs/transformers/) library and its underlying use of the PyTorch framework. -> [!NOTE] The CycloneDX ModelParameters were initially based upon [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) (now archived) which defines [ModelParameters](https://www.tensorflow.org/responsible_ai/model_card_toolkit/api_docs/python/model_card_toolkit/ModelParameters) that include key-value maps for both inputs and outputs alongside an array of their types; these maps will be accomplished using CycloneDX properties and the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy) reserved namespace `cdx:ai-ml:model:parameter` and `cdx:ai-ml:model:hyperparameter` as needed. +> **Note**: The CycloneDX ModelParameters were initially based upon [Tensorflow ModelCard Toolkit](https://github.com/tensorflow/model-card-toolkit) (now archived) which defines [ModelParameters](https://www.tensorflow.org/responsible_ai/model_card_toolkit/api_docs/python/model_card_toolkit/ModelParameters) that include key-value maps for both inputs and outputs alongside an array of their types; these maps will be accomplished using CycloneDX properties and the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy) reserved namespace `cdx:ai-ml:model:parameter` and `cdx:ai-ml:model:hyperparameter` as needed. ###### Example: Model parameters & hyperparameters for the Qwen-7B model @@ -415,8 +415,6 @@ The example model card above contains the following `cdx:ai-ml:model:parameter` The same methodology used to provide model hyperparameter names and values for models can also be applied to model tokenizers by instead using the `cdx:ai-ml:tokenizer:hyperparameter` path and extending it with a path with a parameter name. ---- -
\newpage
diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 04449f1..701ecec 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -66,7 +66,7 @@ Again, the list above contains just a small number of examples of benchmarking d AI benchmarking metrics are standardized, quantitative measures used to evaluate and compare the performance, accuracy, efficiency, and reliability of artificial intelligence models against established, uniform tasks and datasets. They function as a gauge progress in capabilities like reasoning, coding, and language understanding to provide simple comparisons to similar models. -> [!Note] Currently, CycloneDX supports declaring metrics relative to *performance benchmarks* which is the most consistently documented metrics described within producer published model cards. +> **Note**: Currently, CycloneDX supports declaring metrics relative to *performance benchmarks* which is the most consistently documented metrics described within producer published model cards. #### Performance metrics diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 99469c2..72a8da4 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -145,7 +145,7 @@ Used to provide list describing known ethical considerations when using a model. * **Name**: A concise name for the ethical considerations. * **Mitigation strategy**: A corresponding (recommended) mitigation strategy, for the named consideration, to take when using the model. -> [!Note] Since there is no agreed-upon standard for ethical considerations we recommend using the `name` field to additionally provide further description to clarify the name as needed. +> **Note**: Since there is no agreed-upon standard for ethical considerations we recommend using the `name` field to additionally provide further description to clarify the name as needed. ###### Example: Qwen-7B ethical considerations @@ -257,7 +257,7 @@ Summary of EU AI Act Environmental Disclosure Rules for GPAI Models: * **Reference**: These requirements are outlined in [Article 53](https://artificialintelligenceact.eu/article/53/) and [Annex XI](https://artificialintelligenceact.eu/annex/11/) of the [EU AI Act](https://eur-lex.europa.eu/eli/reg/2024/1689/oj/eng). * **Exemption**: Models released under a free and open-source license are exempt from this disclosure obligation. -> [!Note] Since most trained models are published under some form of open license, most providers do not currently disclose the costs of training their models. +> **Note**: Since most trained models are published under some form of open license, most providers do not currently disclose the costs of training their models. Each "consumption" entry consists of the following which are explained in more detail below: @@ -354,8 +354,6 @@ This example is for a "fake" model based upon the llama3 architecture. * **unit** - the unit `tCO2eq` is defined by the European Commission and stands for metric tonnes of carbon dioxide equivalent, a standardized unit used to measure the total greenhouse gas emissions (including methane and nitrous oxide) generated during the development, training, and operation of AI systems. ---- -
\newpage
diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 2774cd6..6cea315 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -169,7 +169,7 @@ This section shows how "manufacturing" (i.e., "training") information is provide In short, this is accomplished utilizing objects which are part of the [CycloneDX Manufacturing Bill-of-Materials (or MBOM)](https://cyclonedx.org/capabilities/mbom/) to describe the frameworks, systems, platforms and libraries used to train the model against a detailed workflow-task description. -**Note**: The "manufacturing" information may be included within the ML-BOM itself or provided as a separate MBOM and cross-linked to each other using the CycloneDX `BOMLink` (see [BOM-Link](https://cyclonedx.org/capabilities/bomlink/) documentation). +> **Note**: The "manufacturing" information may be included within the ML-BOM itself or provided as a separate MBOM and cross-linked to each other using the CycloneDX `BOMLink` (see [BOM-Link](https://cyclonedx.org/capabilities/bomlink/) documentation). #### Declaring hardware and software training components diff --git a/ML-BOM/en/0x91-Appendix-B_References.md b/ML-BOM/en/0x91-Appendix-B_References.md index 86cd3d1..3e7d29d 100644 --- a/ML-BOM/en/0x91-Appendix-B_References.md +++ b/ML-BOM/en/0x91-Appendix-B_References.md @@ -81,7 +81,7 @@ Huggingface model (repositories) typically support the `.safetensors` Huggingfac ONNX models are typically single file format ending with the `.onnx` extension. -Note: Most ONNX models have transitioned to and are now registered in Huggingface, but are downloaded from linked GitHub repository files not within the HF repo. itself. +> **Note**: Most ONNX models have transitioned to and are now registered in Huggingface, but are downloaded from linked GitHub repository files not within the HF repo. itself. * Huggingface * [onnx/DenseNet-121-9](https://huggingface.co/onnx/DenseNet-121-9/tree/main) - `densenet-9.onnx` From 0f65684f7f901c3a502f84a9e21ccafa55c1f526 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Thu, 19 Feb 2026 15:37:10 -0600 Subject: [PATCH 109/111] Fix empty link for glossary - prompt engineering Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x90-Appendix-A_Glossary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ML-BOM/en/0x90-Appendix-A_Glossary.md b/ML-BOM/en/0x90-Appendix-A_Glossary.md index d59e6f5..5ce3353 100644 --- a/ML-BOM/en/0x90-Appendix-A_Glossary.md +++ b/ML-BOM/en/0x90-Appendix-A_Glossary.md @@ -36,7 +36,7 @@ A neural network consists of connected units or nodes called artificial neurons, the process of structuring or crafting an instruction in order to produce better outputs from a generative artificial intelligence (AI) model. It typically involves designing clear queries, adding relevant context, and refining wording to guide the model toward more accurate, useful, and consistent responses/ [1] -[1] [Wikipedia - prompt engineering]() +[1] [Wikipedia - prompt engineering](https://en.wikipedia.org/wiki/Prompt_engineering) ##### Quantization From c51142f5fdf23184c17f36547427ab444c961cc4 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 20 Feb 2026 10:52:38 -0600 Subject: [PATCH 110/111] Final review: fix typos, etc. Signed-off-by: Matt Rutkowski --- ML-BOM/en/0x22-Design-Model-Card-Parameters.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index fb120fa..3ec6f60 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -355,14 +355,14 @@ The JSON below shows how a few of the [Qwen/Qwen-7B](https://huggingface.co/Qwen ..., "modelCard": { "modelParameters": { - ... + ..., "properties": [ { - "name": "cdx:ai-ml:model:parameter:parameter:count", + "name": "cdx:ai-ml:model:parameter:count", "value": "7B" }, { - "name": "cdx:ai-ml:model:parameter:parameter:tune_methods", + "name": "cdx:ai-ml:model:parameter:tune_methods", "value": "sft, rlhf" }, { From 7d7e88647693bb81d369f635f7d103efa4e917b4 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Mon, 2 Mar 2026 10:08:00 -0600 Subject: [PATCH 111/111] Adjust hyperparam. to prop. tax. changes plus use commented ... Signed-off-by: Matt Rutkowski --- .../0x20-Design-Model-Component-Metadata.md | 50 ++++++++--------- .../en/0x22-Design-Model-Card-Parameters.md | 56 ++++++++++--------- ...Design-Model-Card-Quantitative-Analysis.md | 12 ++-- .../0x24-Design-Model-Card-Considerations.md | 28 +++++----- ...x40-Design-Additional-Model-Information.md | 38 ++++++------- 5 files changed, 94 insertions(+), 90 deletions(-) diff --git a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md index 2104f6a..68e545d 100644 --- a/ML-BOM/en/0x20-Design-Model-Component-Metadata.md +++ b/ML-BOM/en/0x20-Design-Model-Component-Metadata.md @@ -58,11 +58,11 @@ The CycloneDX JSON pseudocode below shows how an ML model would be declared as t "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", "purl": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", "version": "ef3c5c9c57b252f3149c1408daf4d649ec8b6c85", - ... + // ... } - ... + // ... } - ... + // ... } ``` @@ -87,7 +87,7 @@ Since the the model repository is hosted in Hugging Face Hub, the [Huggingface p ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... + // ... "metadata": { "component": @@ -112,7 +112,7 @@ Since the the model repository is hosted in Hugging Face Hub, the [Huggingface p } ], "modelCard": { - ... + // ... } } } @@ -150,7 +150,7 @@ If the model being described by an ML-BOM is instead hosted in a GitHub reposito "type": "machine-learning-model", "purl": "pkg:github/onnx/models@4c46cd00fbdb7cd30b6c1c17ab54f2e1f4f7b177#validated/vision/object_detection_segmentation/tiny-yolov2/model", "bom-ref": "pkg:github/onnx/models@244fd47#tiny-yolov2/model" - ... + // ... } ``` @@ -169,9 +169,9 @@ The following example shows how a registered names for a fictional company ACME "name": "acme:research:model:llm:id", "value": "MODEL-ID-12345-INTERNAL" }, - ... + // ... ], - ... + // ... } ``` @@ -201,7 +201,7 @@ Each can be specifically identified in a CycloneDX component using a Package URL "specVersion": "1.7", "serialNumber": "urn:uuid:1ad676cb-6b40-4068-ae91-ebd1533dbf58", "version": 1, - ..., + // ..., "components": [ { "name": "Qwen3-8B-Q4_K_M.gguf", @@ -209,10 +209,10 @@ Each can be specifically identified in a CycloneDX component using a Package URL "bom-ref": "pkg:huggingface/Qwen/Qwen3-8B-GGUF@7c41481#Qwen3-8B-Q4_K_M.gguf", "purl": "pkg:huggingface/Qwen/Qwen3-8B-GGUF@7c41481f57cb95916b40956ab2f0b139b296d974#Qwen3-8B-Q4_K_M.gguf", "version": "7c41481f57cb95916b40956ab2f0b139b296d974", - ... + // ... } ], - ... + // ... } ``` @@ -245,14 +245,14 @@ The simplified JSON below shows how to declare a few of the files from the model ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... + // ..., "metadata": { "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ... + // ... "components": [ { "type": "file", @@ -260,7 +260,7 @@ The simplified JSON below shows how to declare a few of the files from the model "description": "Model configuration file using the 'QWenLMHeadModel' model class in Hugging Face Transformers", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@e7a368b#config.json", "purl": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#config.json", - ... + // ... }, { "type": "file", @@ -268,7 +268,7 @@ The simplified JSON below shows how to declare a few of the files from the model "description": "Python 'QWenConfig' class implementation for the Qwen-7B model using Hugging Face Transformers", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@a6ca629#configuration_qwen.py", "purl": "pkg:huggingface/Qwen/Qwen-7B@a6ca629d063f56f34d184852301e8852a7afbd58#configuration_qwen.py", - ... + // ... }, { "type": "data", @@ -278,9 +278,9 @@ The simplified JSON below shows how to declare a few of the files from the model "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00001-of-00008.safetensors", "data": { "type": "dataset", - ... + // ... } - ... + // ... }, { "type": "data", @@ -290,15 +290,15 @@ The simplified JSON below shows how to declare a few of the files from the model "purl": "pkg:huggingface/Qwen/Qwen-7B@abcb6d6d8ec63ce606f816e2d08072da6309f965#model-00002-of-00008.safetensors", "data": { "type": "dataset", - ... + // ... } - ... + // ... }, - ... + // ... ] } } - ... + // ... } ``` @@ -307,7 +307,7 @@ then the model component's new hierarchy of composing files would be described a ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ..., + // ..., "composition": [ { "aggregate": "complete", @@ -316,7 +316,7 @@ then the model component's new hierarchy of composing files would be described a ] } ], - ... + // ... } ``` @@ -343,7 +343,7 @@ It is important to capture any of these transformations as the model's lineage o ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ..., + // ..., "metadata": { "component": { "type": "machine-learning-model", @@ -352,7 +352,7 @@ It is important to capture any of these transformations as the model's lineage o "bom-ref": "pkg:huggingface/unsloth/Llama-3.2-3B-Instruct@1.0.0", "publisher": "Unsloth", "description": "A pre-optimized, specialized versions of the meta-llama/Llama-3.2-3B-Instruct model designed to work seamlessly with Unsloth's training framework", - ..., + // ..., "pedigree": { "ancestors": [ { diff --git a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md index 3ec6f60..65127aa 100644 --- a/ML-BOM/en/0x22-Design-Model-Card-Parameters.md +++ b/ML-BOM/en/0x22-Design-Model-Card-Parameters.md @@ -83,14 +83,14 @@ This example shows best practice for the Qwen-7B model using information publish ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ..., + // ..., "metadata": { "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., + // ..., "modelCard": { "modelParameters": { "task": "text-generation", @@ -99,7 +99,7 @@ This example shows best practice for the Qwen-7B model using information publish "approach": { "type": "supervised" }, - ... + // ... } } } @@ -121,14 +121,14 @@ This shows how the Qwen research team disclosed comprehensive details about the ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... + // ..., "metadata": { "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., + // ..., "externalReferences": [ { "type": "documentation", @@ -136,7 +136,7 @@ This shows how the Qwen research team disclosed comprehensive details about the "comment": "Qwen Technical Report" } ], - ... + // ... } } } @@ -188,10 +188,10 @@ This example shows a model fine-tuned (by a fictional "ACME Health" company) fro "bom-ref": "pkg:huggingface/acme-health/custom-Llama3-Med42-8B@2ee9dc9", "purl": "pkg:huggingface/acme-health/custom-Llama3-Med42-8B@2ee9dc99-cc50-4490-9d6e-9ebf6e39f82f", "description": "Customized Med42-v2 large language models (LLMs) which uses the Llama3 architecture and fine-tuned using private clinical dataset." - ..., + // ..., "modelCard": { "modelParameters": { - ..., + // ..., "datasets": [ { "type": "dataset", @@ -202,7 +202,7 @@ back dataset", "url": "https://huggingface.co/datasets/openbmb/UltraFeedback" } }, - ..., + //..., { "type": "dataset", "name": "ACME Midwest health data", @@ -212,7 +212,7 @@ back dataset", } } ], - ... + // ... } } } @@ -251,10 +251,10 @@ The public datasets, as documented in the model's research paper include: "bom-ref": "pkg:huggingface/acme-health/custom-Llama3-Med42-8B@ceab7e7", "purl": "pkg:huggingface/acme-health/Llama3-Med42-8B@ceab7e7ee4b9dbde7ba82867f34274db51487d83", "description": "an open, clinical large language models (LLM) instruct and preference-tuned by M42 to expand access to medical knowledge. Built off LLaMA-3 and designed to provide high-quality answers to medical questions." - ..., + // ..., "modelCard": { "modelParameters": { - ..., + // ..., "datasets": [ { "ref": "pkg:huggingface/openbmb/UltraFeedback@40b4365" @@ -263,26 +263,26 @@ The public datasets, as documented in the model's research paper include: "ref": "pkg:huggingface/snorkelai/Snorkel-Mistral-PairRM-DPO@07af5d0a" } ], - ... + // ... } } } }, - ..., + // ..., "components": [ { "name": "UltraFeed-back dataset", "type": "data", "bom-ref": "pkg:huggingface/openbmb/UltraFeedback@40b4365", "purl": "pkg:huggingface/openbmb/UltraFeedback@40b436560ca83a8dba36114c22ab3c66e43f6d5e", - ... + // ... }, { "name": "UltraFeed-back dataset", "type": "data", "bom-ref": "pkg:huggingface/snorkelai/Snorkel-Mistral-PairRM-DPO@07af5d0a", "purl": "pkg:huggingface/snorkelai/Snorkel-Mistral-PairRM-DPO@07af5d0a875b4c692dfaff6c675b10af07b45511", - ... + // ... } ] } @@ -301,16 +301,16 @@ In order to provide information on model parameters and hyperparameters using ex ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... + // ..., "metadata": { "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., + // ..., "modelCard": { - ..., + // ..., "inputs": [ {"format": "string"} ], @@ -345,25 +345,29 @@ The JSON below shows how a few of the [Qwen/Qwen-7B](https://huggingface.co/Qwen ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... + // ..., "metadata": { "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., + // ..., "modelCard": { "modelParameters": { - ..., + // ..., "properties": [ { "name": "cdx:ai-ml:model:parameter:count", "value": "7B" }, { - "name": "cdx:ai-ml:model:parameter:tune_methods", - "value": "sft, rlhf" + "name": "cdx:ai-ml:model:parameter:tune_method", + "value": "sft" + }, + { + "name": "cdx:ai-ml:model:parameter:tune_method", + "value": "rlhf" }, { "name": "cdx:ai-ml:model:hyperparameter:num_hidden_layers", @@ -385,10 +389,10 @@ The JSON below shows how a few of the [Qwen/Qwen-7B](https://huggingface.co/Qwen "name": "cdx:ai-ml:model:hyperparameter:quantization", "value": "BF16" }, - ... + // ... ] }, - ... + // ... } } } diff --git a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md index 701ecec..86b79d2 100644 --- a/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md +++ b/ML-BOM/en/0x23-Design-Model-Card-Quantitative-Analysis.md @@ -100,9 +100,9 @@ The MMLU score from the table would be declared as a performance metric as follo { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., + // ..., "modelCard": { - ... + // ..., "quantitativeAnalysis": { "performanceMetrics": [ { @@ -161,17 +161,17 @@ This could be encoded in a CycloneDX ML-BOM model card as follows: ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ..., + // ..., "metadata": { "component": { "type": "machine-learning-model", - ..., + // ..., "modelCard": { - ..., + // ..., "quantitativeAnalysis": { - ..., + // ..., "graphics": [ { "description": "benchmark_score", diff --git a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md index 72a8da4..92dcc2c 100644 --- a/ML-BOM/en/0x24-Design-Model-Card-Considerations.md +++ b/ML-BOM/en/0x24-Design-Model-Card-Considerations.md @@ -26,9 +26,9 @@ This example shows a list for what kind of user and use case information would b "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., + // ..., "modelCard": { - ..., + // ..., "considerations": { "users": [ "Software developer", @@ -81,9 +81,9 @@ This example shows a list for what kind of technical limitations might be associ "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., + // ..., "modelCard": { - ..., + // ..., "considerations": { "technicalLimitations": [ "Greedy Decoding Degradation. The model is optimized for sampling-based generation. Using greedy decoding (temperature=0) can lead to performance degradation, repetitive loops, and \"stuck\" reasoning steps, particularly in the new Thinking Mode", @@ -118,9 +118,9 @@ This example how to provide performance tradeoffs against a few that have been a "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., + // ..., "modelCard": { - ..., + // ..., "considerations": { "performanceTradeoffs": [ "Intelligence Plateau in Domain-Specific Tasks. Research indicates that for specialized fields like legal text analysis, performance often flattens beyond the 7B parameter mark. While efficient, the 7B model may not offer the incremental reasoning gains found in the 32B or 235B models for complex, high-stakes domain reasoning.", @@ -155,9 +155,9 @@ Based on technical reports and safety evaluations such as Qwen3Guard, the follow "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., + // ..., "modelCard": { - ..., + // ..., "considerations": { "ethicalConsiderations": [ { @@ -184,7 +184,7 @@ Based on technical reports and safety evaluations such as Qwen3Guard, the follow "name": "Instruction Misalignment. In-context learning can sometimes lead to \"emergent misalignment\", where the model prioritizes following a user's conversational style over established safety boundaries.", "mitigationStrategy": "Standardize output formats using system prompts and utilize the \"hard switch\" to disable the model's internal thinking mode when maximum safety and predictability are required." }, - ... + // ... ] } } @@ -215,11 +215,11 @@ This example shows how fairness assessment information would be included in a a "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., + // ..., "modelCard": { - ..., + // ..., "considerations": { - ..., + // ..., "fairnessAssessments": [ { "groupAtRisk": "People identified by characteristics such as race, gender, and disability status.", @@ -231,7 +231,7 @@ This example shows how fairness assessment information would be included in a a "harms": "Quality-of-Service Harm: The model may provide high-quality, nuanced reasoning in English or Mandarin but offer oversimplified, factually incorrect, or \"hallucinated\" information when queried in other supported languages.", "mitigationStrategy": "Cross-Lingual Alignment: Developers can use multilingual Supervised Fine-Tuning (SFT). By training on additional high-quality, parallel corpora from other languages on \"reasoning capabilities\" (e.g., logic, math, coding)." }, - ... + // ... ] } } @@ -303,7 +303,7 @@ This example is for a "fake" model based upon the llama3 architecture. { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/FakeAI/Llama3@abcd123", - ..., + // ..., "modelCard": { "considerations": { "environmentalConsiderations": { diff --git a/ML-BOM/en/0x40-Design-Additional-Model-Information.md b/ML-BOM/en/0x40-Design-Additional-Model-Information.md index 6cea315..b26fada 100644 --- a/ML-BOM/en/0x40-Design-Additional-Model-Information.md +++ b/ML-BOM/en/0x40-Design-Additional-Model-Information.md @@ -38,7 +38,7 @@ Models are can be trained in one or more languages (i.e., multilingual models). { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/FakeAI/MultilingualLLama", - ..., + // ..., "properties": [ { "name": "cdx:ai-ml:model:languages", @@ -65,13 +65,13 @@ This section describes how to "tag" model components with non-standard keywords { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/FakeAI/TxtSpeak3", - ..., + // ..., "tags": [ "pytorch", "transformers", "text-to-speech", "speech-to-speech", - ... + // ... ] } ``` @@ -97,14 +97,14 @@ Using the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model in Hugging F ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ... + // ... "metadata": { "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ... + // ..., "components": [ { "type": "library", @@ -112,7 +112,7 @@ Using the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model in Hugging F "description": "Python tokenization classes for QWen (QWenTokenizer)", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@e7a368b#tokenization_qwen.py", "purl": "pkg:huggingface/Qwen/Qwen-7B@e7a368b0774370edec29674e7c51f52fc7663f59#tokenization_qwen.py", - ..., + // ..., "properties": [ { "name": "cdx:ai-ml:model:tokenizer", @@ -120,11 +120,11 @@ Using the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model in Hugging F } ] }, - ... + // ... ] } } - ... + // ... } ``` @@ -139,14 +139,14 @@ For the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model, the chat temp ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ..., + // ..., "metadata": { "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/Qwen/Qwen-7B@ef3c5c9", - ..., + // ..., "properties": [ { "name": "cdx:ai-ml:model:template:chat", @@ -155,7 +155,7 @@ For the [Qwen/Qwen-7B](https://huggingface.co/Qwen/Qwen-7B) model, the chat temp ] } }, - ... + // ... } ``` @@ -180,16 +180,16 @@ First, create entries for all the "components" used in the training process as p ```json { "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", - ..., + // ..., "metadata": { "component": { "type": "machine-learning-model", "bom-ref": "pkg:huggingface/FakeAI/llama3@abcd", } }, - ..., + // ..., "formulation": { - ..., + // ..., "components": [ { "type": "container", @@ -233,10 +233,10 @@ First, create entries for all the "components" used in the training process as p "description": "NVIDIA H100 Tensor Core GPU PCIe Device", "bom-ref": "nvidia-h100-pcie-gpu-1", }, - ... + // ... ] }, - ... + // ... } ``` @@ -252,7 +252,7 @@ After the hardware and software "stack" of training components have been declare ```json "formulation": { - ..., + // ..., "workflows": [ { "name": "Model training workflow", @@ -264,7 +264,7 @@ After the hardware and software "stack" of training components have been declare "steps": [ ... ], "inputs": [ ... ], "outputs": [ ... ], - ... + // ... } ] } @@ -283,7 +283,7 @@ Lastly, you would describe the component "stack" as a graph of `runtimeTopology` "workflows": [ { "tasks": [ ... ], - ..., + // ..., "runtimeTopology": [ { "ref": "pkg:oci/nvidia-pytorch@sha256:f398a0",