Hub transport
Public API
from speedtronic import HubClient
# distributed alias: HubTransport
Errors:
HubError(RuntimeError)
HubUnavailable(HubError)
Constructor
HubClient(
repo_id,
*,
token=None,
cache_dir=None,
api=None,
retry_initial=1.0,
retry_max=60.0,
retry_attempts=6,
sleeper=time.sleep,
)
repo_id is required. The client always treats it as a Hugging Face model repository. api and sleeper are injection points for tests.
The api property lazily constructs huggingface_hub.HfApi(token=token). If the SDK is missing, operations raise HubUnavailable.
Retry behavior
Every network/repository operation is wrapped by _retry:
attempt immediately
→ wait retry_initial
→ double delay after each failure
→ cap at retry_max
→ raise HubUnavailable after retry_attempts
With defaults, sleeps are 1, 2, 4, 8, and 16 seconds before the sixth final attempt.
The wrapper catches every Exception, including permanent authentication, malformed request, and programming errors. There is no jitter, retry classification, or explicit request timeout.
Repository methods
create_repo(private=True)
Calls:
api.create_repo(
repo_id,
repo_type="model",
private=private,
exist_ok=True,
)
exist_ok=True does not verify that an existing repository is private.
add_collaborator(username, permission="write")
Valid permissions:
read
write
admin
Attempts the newer keyword API, then a positional compatibility form. Missing SDK support raises HubError.
list_files()
Returns sorted repository filenames.
file_exists(remote_path)
Builds a set from list_files() and checks membership. This is a full repository listing, not a direct existence API.
upload(local_path, remote_path)
Verifies local existence and calls api.upload_file with compatibility handling.
download(remote_path, local_path=None)
- Creates a temporary directory under
cache_dir. - Uses an API download method when available, then the top-level SDK helper.
- Copies the downloaded file to the destination.
- Removes the temporary directory in
finally.
The final copy is not atomic.
JSON methods
read_json(remote_path, default=None)
Checks file_exists, downloads to cache_dir/json/<remote_path>, then parses JSON.
write_json(remote_path, value)
- Writes pretty, sorted JSON under
cache_dir/outgoing. - Uses one deterministic
.tmppath. - Replaces the local staging file.
- Uploads it.
- Copies the local result into the read cache.
The deterministic temporary filename is not process-safe.
Global metadata
@dataclass(frozen=True)
class GlobalMetadata:
outer_step: int
updated_at: str
model_file: str = "global/latest.safetensors"
from_dict() accepts legacy step, missing metadata defaults, and coerces values to int/str. updated_at is informational; synchronization decisions use outer_step.
global_metadata()
Attempts to read global/step_count.json. On HubUnavailable, it can fall back to cached JSON. It can also return cached metadata when the remote path is absent.
Malformed cached JSON is not converted into HubUnavailable.
Global publication
publish_global(
state,
*,
outer_step,
work_dir=None,
updated_at=None,
metadata_extra=None,
) -> GlobalMetadata
Publication sequence:
- Save full state as local
latest.safetensors. - Upload/overwrite
global/latest.safetensors. - Construct metadata.
- Write/upload
global/step_count.json. - Return metadata.
Example:
{
"algorithm": "dumb_diloco",
"model_file": "global/latest.safetensors",
"optimizer": "nesterov_sgd",
"outer_step": 7,
"updated_at": "2026-01-01T12:00:00+00:00"
}
The model and metadata are separate overwrites of fixed paths. A reader can observe old metadata with a newly uploaded model. A metadata failure can leave new weights advertised under the old outer step.
download_global(local_path, metadata=None)
Uses metadata.model_file without an allow-list. Repository write access can redirect workers to another repo file.
Delta publication
upload_delta(
state,
*,
node_id,
local_step,
base_outer_step,
work_dir=None,
metadata=None,
) -> str
Remote path:
nodes/<node_id>/delta_<local_step>.safetensors
Safetensors metadata values are strings:
{
"algorithm": "dumb_diloco",
"base_outer_step": "7",
"local_step": "500",
"node_id": "worker-1"
}
The outer loop derives node/local step from the path and reads base_outer_step from the header.
delta_paths()
Returns all repository paths that start with nodes/ and end in .safetensors. Parsing applies stricter path rules later.
Local cache layout
<cache_dir>/
├── downloads/<remote_path>
├── json/global/step_count.json
├── outgoing/global/step_count.json
└── speedtronic-download-<random>/ # temporary
The cache is not node-scoped and is not automatically rooted under run output.
Failure behavior
All _retry failures become HubUnavailable. Higher coordinator layers usually catch and log those errors, allowing local training to continue. Because permanent errors are retried, an invalid token or repository name can consume the full backoff schedule on every operation.
Security recommendations
- Use the SDK environment credential flow.
- Verify repository visibility after creation.
- Use one token with the minimum required scope.
- Restrict writer accounts.
- Do not treat
model_filemetadata as trusted input from an adversarial writer. - Protect cache files from other local users.
- Monitor unexpected remote paths and updates.
Related: Overview, Outer Loop, and Security.