Skip to content

Change save/load to use results dir paths instead of single files - #346

Merged
abdullah-ukaea merged 11 commits into
devfrom
wk9874/models/use_dir_storage
Aug 6, 2026
Merged

Change save/load to use results dir paths instead of single files#346
abdullah-ukaea merged 11 commits into
devfrom
wk9874/models/use_dir_storage

Conversation

@wk9874

@wk9874 wk9874 commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Changes model storage to now make a directory available with name equal to the model ID, so that more than one file can be saved for a given model.

load() now accepts two parameters, the storage directory, and (optionally) a weights file name. If the weights file name is provided, it should take precedence, otherwise fallback to what the model's save() method will have created.

See example implementation in the disruption_cnn model

Note that when loading files via the UI, we will still only support the loading of a single weights file (for now...)

@wk9874
wk9874 requested a review from praksharma August 3, 2026 11:11
@abdullah-ukaea
abdullah-ukaea self-requested a review August 3, 2026 16:09

@abdullah-ukaea abdullah-ukaea left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I think you need to fix the comment I made in https://github.com/ukaea/toktagger/pull/346/changes#r3705864996 before this can be approved.

the rest are nice to have, nitpicks and some tests that need to be updated. I also noticed some other things which need to be addressed which are not in the git diff.,

Comment thread toktagger/api/models/disruption.py Outdated
Comment thread toktagger/api/worker.py
Comment thread toktagger/api/worker.py Outdated
Comment thread toktagger/api/models/base.py
Comment thread toktagger/api/worker.py Outdated
Comment thread toktagger/api/worker.py Outdated
Comment thread toktagger/api/worker.py
Comment on lines -113 to +109
load_temp_weights_task = model_actor.wrapped_load.remote(str(weights_path))
load_temp_weights_task = model_actor.wrapped_load.remote(
weights_path.parent, weights_path.name
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we check this?

results_dir is meant to be a folder in the model cache, but here it's whatever folder the user's uploaded file came from (e.g. Downloads). A model that ignores the filename and assumes the default name will look in the wrong place. The arguments are also passed positionally instead of by keyword, unlike the rest of the codebase, making them easy to mix up.

Maybe use keyword arguments (results_dir=..., weights_filename=...) to prevent mix-ups, and make sure a model can't end up looking in the wrong place either by documenting this case or having the base class resolve the path itself.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use keyword arguments (results_dir=..., weights_filename=...)

Done this

results_dir is meant to be a folder in the model cache, but here it's whatever folder the user's uploaded file came from (e.g. Downloads)

That's correct, this function is used for loading pretrained weights from the user's system. So on the UI, they'll provide a path to a file on their system which they want to load, and this will be used to try and load it into the model. If that is successful, then the loaded model will be saved back into the model cache with the model ID, so that future calls can access it normally

A model that ignores the filename and assumes the default name will look in the wrong place.

Yeah this is a bit of an issue, I've documented in the docstring of the model base class that if the filename is provided it should take precedence. I'm not sure what else I can do though to enforce this...

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also not sure but that's fine for now since it fails loudly with FileNotFoundError rather than silently loading the wrong fil the user's upload folder is very unlikely to coincidentally already contain a file called weights.model, so a model that ignores the filename will just error out, not misbehave quietly.

Comment on lines -140 to +143
config.settings.models.cache_dir.joinpath(f"{model.id}.model").unlink(
missing_ok=True
)
model_dir = config.settings.models.cache_dir.joinpath(f"{model.id}")
if model_dir.exists():
shutil.rmtree(model_dir)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two small things:

  • f"{model.id}" is an unnecessary f-string wrapping a value that's already a string.
  • checking exists() then calling rmtree() separately is slightly redundant when it can be done in one safe step.

To fix simplify to shutil.rmtree(model_dir, ignore_errors=True) and drop the f-string.

Note that existing <model_id>.model files from before this change will never be found or cleaned up, so old models silently appear as blank/untrained so maybe document that somewhere? e.g. changelog

@wk9874 wk9874 Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f"{model.id}" is an unnecessary f-string wrapping a value that's already a string.

Done

checking exists() then calling rmtree() separately is slightly redundant when it can be done in one safe step.

I think I prefer the way it is, since it won't suppress unexpected errors, while ignore_errors=True would

Note that existing <model_id>.model files from before this change will never be found or cleaned up

True, will add to changelog when we next do a release

Comment thread tests/api/routers/test_models.py
Comment thread toktagger/api/models/base.py Outdated
@abdullah-ukaea

abdullah-ukaea commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Can we fix VideoCNN?

VideoCNN save() and load() (lines

def save(self, file_stem: str):
and
def load(self, file_path: str):
) were never updated to the new signature, so it'll crash with a TypeError the first time anyone trains this example video model.

update save() and load() here to match this branch's changes, the same way disruption.py was updated?

@abdullah-ukaea

Copy link
Copy Markdown
Collaborator

Can we add tests for these gaps?

No test ever loads a file with a name other than weights.model, so the custom filename logic is never actually tested, and no test checks that a model can save more than one file, even though that's the main point of this change.

Relevant file: https://github.com/ukaea/toktagger/blob/wk9874/models/use_dir_storage/tests/models_definitions.py

These lines are the specific problems.

def load(self, results_dir: pathlib.Path, weights_filename: str | None = None):

and

def load(self, results_dir: pathlib.Path, weights_filename: str | None = None):

Could we add a test that loads a weights file with a different name (e.g. my_weights.pt) and checks the right file was used, and have one mock model save a second file alongside its weights, with a test confirming both files survive a save/load cycle?

@abdullah-ukaea abdullah-ukaea added the enhancement New feature or request label Aug 3, 2026
@wk9874

wk9874 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Could we add a test that loads a weights file with a different name (e.g. my_weights.pt) and checks the right file was used

This is covered by test_model_load_local

have one mock model save a second file alongside its weights, with a test confirming both files survive a save/load cycle?
Added to test_model_start_training_params

Will add further tests as part of #319 after this PR is merged, since in that PR I make the functions in worker.py bare functions rather than ray remotes, making them easier to test

@wk9874
wk9874 requested a review from abdullah-ukaea August 6, 2026 09:58

@abdullah-ukaea abdullah-ukaea left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ready to be merged, LGTM, nice work on this one.

@abdullah-ukaea
abdullah-ukaea merged commit 664cfab into dev Aug 6, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants