The config file¶
The config file serves as the input to the mlperf-sysinfo tool. The fields inside it determines which fields get collected, execution path of the tool , and what shape the output file takes(As determined by the particular benchmark rules).
Which profile¶
| Profile | For |
|---|---|
endpoints |
MLPerf Endpoints submissions |
inference |
MLPerf Inference submissions |
training |
MLPerf Training submissions |
profile: defaults to endpoints.
Getting one¶
init writes a commented starter config for the profile you name, containing
only the fields that profile reads:
check names every field still missing or still holding starter text, and
reaches every machine the config mentions, before you spend a capture finding
out.
Every CHANGEME below is a field check will stop on.
What init endpoints writes
# MLPerf system description -- endpoints profile
#
# mlperf-sysinfo check -c sysinfo.yaml # validate + reach everything
# mlperf-sysinfo capture -c sysinfo.yaml # collect and write the file
#
# Anything the tool can detect for itself -- CPU, memory, accelerators, node
# counts, framework version, parallelism and batch size -- is deliberately
# absent below. Only what cannot be detected belongs in this file.
profile: endpoints
output:
dir: results/sysinfo
system:
name: CHANGEME # e.g. H100x8_vLLM
shortened_name: CHANGEME # at most 20 characters, e.g. H100x8
availability: available # available | preview | rdi
accelerator: cuda # cuda | rocm | xpu | none
cooling: air # air | liquid | passive
nodes:
include_local: false # is this machine part of the system under test?
ssh:
- user@node1
# - user@node2:2222
ssh_key_preconfigured: false
# Optional. Only needed for disaggregated setups, where nodes serve
# different functions. 'match' is compared case-insensitively against the
# detected accelerator model name.
# groups:
# prefill:
# - { match: NVIDIA H100, count: 2 }
# decode:
# - { match: NVIDIA H100, count: 5 }
serving:
# The endpoint under test, and also probed for the framework name/version.
# Rules 8.2 allow a description instead of a URL, for a hosted endpoint with
# no public address -- e.g. "Managed endpoint, us-east-1, no public URL".
url: http://node1:8000
node: user@node1 # where the server process runs
log: /tmp/serving.log # server stdout/stderr must be redirected here
framework: auto # auto | vllm | sglang | trtllm
submission:
division: standardized # standardized | serviced | rdi
# container_link: https://... # container the submission ran in
notes:
hardware: "" # becomes hw_notes on every node type
software: "" # becomes sw_notes on every node type
# other_hardware: ""
# How the stack was configured for this run. The parallelism degrees and batch
# size are read from serving.log, so they are not listed here -- these three
# cannot be detected from anything on the machine.
run:
# node_config: "prefill: 2x H100; decode: 6x H100" # defaults to a summary of nodes.groups
# config_summary_notes: "" # anything the parallelism fields do not capture
# link_config: https://github.com/myorg/submission/tree/main/configs
What init inference writes
# MLPerf system description -- inference profile
#
# mlperf-sysinfo check -c sysinfo.yaml # validate + reach everything
# mlperf-sysinfo capture -c sysinfo.yaml # collect and write the file
#
# Writes the flat field set the MLPerf Inference submission checker expects.
# Anything detectable is absent below on purpose -- only what cannot be
# detected belongs in this file.
profile: inference
output:
dir: results/sysinfo
system:
name: CHANGEME # e.g. 8xH100_TRT
category: datacenter # datacenter | edge
availability: available # available | preview | rdi
accelerator: cuda # cuda | rocm | xpu | none
cooling: air
# type_detail: ""
nodes:
include_local: true # single machine: describe the one running this
ssh: [] # add user@host entries for a multi-node system
ssh_key_preconfigured: false
submission:
submitter: CHANGEME
contact: CHANGEME@example.com
division: closed # closed | open
notes:
hardware: ""
software: ""
What init training writes
# MLPerf system description -- training profile
#
# mlperf-sysinfo check -c sysinfo.yaml # validate + reach everything
# mlperf-sysinfo capture -c sysinfo.yaml # collect and write the file
#
# Writes the flat field set mlperf_logging/system_desc_checker validates.
# Anything detectable -- CPU, memory, accelerators, node count, OS, software
# stack -- is deliberately absent below. Only what cannot be detected belongs
# in this file.
#
# The output is named after system.name, because a training submission stores
# it as <submitter>/systems/<system_name>.json.
profile: training
output:
dir: results/sysinfo
system:
name: CHANGEME # e.g. dgx-h100-n8 -- also the output filename
# Training accepts exactly these four, and nothing else. Plain "available"
# is not one of them: training splits it into on-premise and cloud.
availability: Available on-premise
# Available on-premise
# Available cloud
# Preview
# Research, Development, or Internal (RDI)
accelerator: cuda # cuda | rocm | xpu | none
cooling: air # air | liquid | passive
# How the nodes are wired to each other. No probe can see past the local
# NIC. A single-node system should say so rather than leave it blank.
networking_topology: CHANGEME # e.g. "rail-optimized fat tree, 8x400G per node"
nodes:
include_local: true # single machine: describe the one running this
ssh: [] # add user@host entries for a multi-node system
ssh_key_preconfigured: false
training:
# The framework and version the run used. It lives inside the container
# image, which this tool never opens.
framework: CHANGEME # e.g. "NVIDIA PyTorch Release 25.04"
# Optional short tag for that build. Written only when set.
# framework_name: ngc25.04_pytorch
submission:
submitter: CHANGEME
division: closed # closed | open
notes:
hardware: "" # becomes hw_notes
software: "" # becomes sw_notes
output — where the file lands¶
| Key | Type | Default | Notes |
|---|---|---|---|
dir |
path | . |
Relative paths resolve against the config file, not the cwd |
file |
string | profile's own | Output filename |
Only the deliverable is written to dir. Everything the collection layer
produces goes into dir/.mlperf-sysinfo/ — see
Architecture.
${VAR} — secrets stay out of the file¶
Any ${VAR} anywhere in the config is replaced from the environment, including
inside lists. An unset variable is a config problem, reported against its path:
extends — share org defaults¶
# ~/.mlperf/org.yaml
submission:
division: standardized
run:
link_config: https://github.com/myorg/submission/tree/main/configs
The child wins. Nested maps merge; lists replace wholesale. A chain that loops back on itself stops at a depth limit rather than following it round forever:
Empty, unset, and absent¶
Three states that look alike in YAML and are not the same thing:
| Written as | Means |
|---|---|
cooling: air |
Set |
cooling: |
Unset. Stays unset; nothing is guessed |
ssh: with every entry commented out |
Absent. Treated as if the key were not there |
The last one is why deleting the final entry under nodes.ssh — or under run:
— is not an error.
Emptying nodes.ssh is an error when nothing else is left to look at
An absent ssh list is only fine while some other machine is still named.
With include_local: false and no serving.node either, there is nothing
to collect from, and the config is rejected before any node is contacted:
Leftover starter text¶
A config still carrying starter text has not been filled in, and check
refuses it. Two patterns are recognised anywhere in the file:
- anything containing
changeme(soCHANGEME@example.comcounts) - anything matching
Insert … hereor<…>
The insert rule is anchored on purpose, so genuine prose survives:
Every string is scanned, not only the fields your profile requires — starter
text in any field still reaches the submission file. The check report calls
these placeholder.
Unknown and misspelled options¶
check reports an error for any option it does not recognise, and names a
real option where one is close enough:
$ mlperf-sysinfo check -c sysinfo.yaml
error sysinfo.yaml: config is not valid
system.categry: unknown option. Did you mean "category"?
nodes.include-local: unknown option. Did you mean "include_local"?
submission.divison: unknown option. Did you mean "division"?
Matching ignores case, and treats - and _ as the same character.