Skip to content

feat: display model storage size #7877

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 9, 2025
Merged
1 change: 1 addition & 0 deletions invokeai/app/api/routers/model_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ def add_cover_image_to_model_config(config: AnyModelConfig, dependencies: Type[A
"config_path": "string",
"key": "string",
"hash": "string",
"file_size": 1,
"description": "string",
"source": "string",
"converted_at": 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class ModelRecordChanges(BaseModelExcludeNull):
type: Optional[ModelType] = Field(description="Type of model", default=None)
key: Optional[str] = Field(description="Database ID for this model", default=None)
hash: Optional[str] = Field(description="hash of model file", default=None)
file_size: Optional[int] = Field(description="Size of model file", default=None)
format: Optional[str] = Field(description="format of model file", default=None)
trigger_phrases: Optional[set[str]] = Field(description="Set of trigger phrases for this model", default=None)
default_settings: Optional[MainModelDefaultSettings | ControlAdapterDefaultSettings] = Field(
Expand Down
2 changes: 2 additions & 0 deletions invokeai/app/services/shared/sqlite/sqlite_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from invokeai.app.services.shared.sqlite_migrator.migrations.migration_16 import build_migration_16
from invokeai.app.services.shared.sqlite_migrator.migrations.migration_17 import build_migration_17
from invokeai.app.services.shared.sqlite_migrator.migrations.migration_18 import build_migration_18
from invokeai.app.services.shared.sqlite_migrator.migrations.migration_19 import build_migration_19
from invokeai.app.services.shared.sqlite_migrator.sqlite_migrator_impl import SqliteMigrator


Expand Down Expand Up @@ -59,6 +60,7 @@ def init_db(config: InvokeAIAppConfig, logger: Logger, image_files: ImageFileSto
migrator.register_migration(build_migration_16())
migrator.register_migration(build_migration_17())
migrator.register_migration(build_migration_18())
migrator.register_migration(build_migration_19(app_config=config))
migrator.run_migrations()

return db
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import sqlite3

from invokeai.app.services.config import InvokeAIAppConfig
from invokeai.app.services.shared.sqlite_migrator.sqlite_migrator_common import Migration
from invokeai.backend.model_manager.model_on_disk import ModelOnDisk


class Migration19Callback:
def __init__(self, app_config: InvokeAIAppConfig):
self.models_path = app_config.models_path

def __call__(self, cursor: sqlite3.Cursor) -> None:
self._populate_size(cursor)
self._add_size_column(cursor)

def _add_size_column(self, cursor: sqlite3.Cursor) -> None:
cursor.execute(
"ALTER TABLE models ADD COLUMN file_size INTEGER "
"GENERATED ALWAYS as (json_extract(config, '$.file_size')) VIRTUAL NOT NULL"
)

def _populate_size(self, cursor: sqlite3.Cursor) -> None:
all_models = cursor.execute("SELECT id, path FROM models;").fetchall()

for model_id, model_path in all_models:
mod = ModelOnDisk(self.models_path / model_path)
cursor.execute(
"UPDATE models SET config = json_set(config, '$.file_size', ?) WHERE id = ?", (mod.size(), model_id)
)


def build_migration_19(app_config: InvokeAIAppConfig) -> Migration:
return Migration(
from_version=18,
to_version=19,
callback=Migration19Callback(app_config),
)
2 changes: 2 additions & 0 deletions invokeai/backend/model_manager/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ def json_schema_extra(schema: dict[str, Any]) -> None:
path: str = Field(
description="Path to the model on the filesystem. Relative paths are relative to the Invoke root directory."
)
file_size: int = Field(description="The size of the model in bytes.")
name: str = Field(description="Name of the model.")
type: ModelType = Field(description="Model type")
format: ModelFormat = Field(description="Model format")
Expand Down Expand Up @@ -241,6 +242,7 @@ def from_model_on_disk(cls, mod: ModelOnDisk, **overrides):
fields["key"] = fields.get("key") or uuid_string()
fields["description"] = fields.get("description") or f"{base.value} {type.value} model {name}"
fields["repo_variant"] = fields.get("repo_variant") or mod.repo_variant()
fields["file_size"] = fields.get("file_size") or mod.size()

return cls(**fields)

Expand Down
2 changes: 2 additions & 0 deletions invokeai/backend/model_manager/legacy_probe.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
SubmodelDefinition,
)
from invokeai.backend.model_manager.load.model_loaders.generic_diffusers import ConfigLoader
from invokeai.backend.model_manager.model_on_disk import ModelOnDisk
from invokeai.backend.model_manager.taxonomy import (
AnyVariant,
BaseModelType,
Expand Down Expand Up @@ -207,6 +208,7 @@ def probe(
)
fields["format"] = ModelFormat(fields.get("format")) if "format" in fields else probe.get_format()
fields["hash"] = fields.get("hash") or ModelHash(algorithm=hash_algo).hash(model_path)
fields["file_size"] = fields.get("file_size") or ModelOnDisk(model_path).size()

fields["default_settings"] = fields.get("default_settings")

Expand Down
1 change: 1 addition & 0 deletions invokeai/frontend/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"chakra-react-select": "^4.9.2",
"cmdk": "^1.0.0",
"compare-versions": "^6.1.1",
"filesize": "^10.1.6",
"fracturedjsonjs": "^4.0.2",
"framer-motion": "^11.10.0",
"i18next": "^23.15.1",
Expand Down
8 changes: 8 additions & 0 deletions invokeai/frontend/web/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions invokeai/frontend/web/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@
"deleteMsg2": "This WILL delete the model from disk if it is in the InvokeAI root folder. If you are using a custom location, then the model WILL NOT be deleted from disk.",
"description": "Description",
"edit": "Edit",
"fileSize": "File Size",
"fluxRedux": "FLUX Redux",
"height": "Height",
"huggingFace": "HuggingFace",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { selectModelManagerV2Slice, setSelectedModelKey } from 'features/modelMa
import ModelBaseBadge from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelBaseBadge';
import ModelFormatBadge from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelFormatBadge';
import { toast } from 'features/toast/toast';
import { filesize } from 'filesize';
import type { MouseEvent } from 'react';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
Expand Down Expand Up @@ -92,6 +93,9 @@ const ModelListItem = ({ model }: ModelListItemProps) => {
<Text fontWeight="semibold" noOfLines={1} wordBreak="break-all">
{model.name}
</Text>
<Text variant="subtext" fontStyle="italic">
{filesize(model.file_size)}
</Text>
<Spacer />
</Flex>
<Text variant="subtext" noOfLines={1}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ModelConvertButton } from 'features/modelManagerV2/subpanels/ModelPanel
import { ModelEditButton } from 'features/modelManagerV2/subpanels/ModelPanel/ModelEditButton';
import { ModelHeader } from 'features/modelManagerV2/subpanels/ModelPanel/ModelHeader';
import { TriggerPhrases } from 'features/modelManagerV2/subpanels/ModelPanel/TriggerPhrases';
import { filesize } from 'filesize';
import { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import type { AnyModelConfig } from 'services/api/types';
Expand Down Expand Up @@ -50,6 +51,7 @@ export const ModelView = memo(({ modelConfig }: Props) => {
<ModelAttrView label={t('modelManager.modelType')} value={modelConfig.type} />
<ModelAttrView label={t('common.format')} value={modelConfig.format} />
<ModelAttrView label={t('modelManager.path')} value={modelConfig.path} />
<ModelAttrView label={t('modelManager.fileSize')} value={filesize(modelConfig.file_size)} />
{modelConfig.type === 'main' && (
<ModelAttrView label={t('modelManager.variant')} value={modelConfig.variant} />
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,7 @@ describe('Graph', () => {
key: 'b00ee8df-523d-40d2-9578-597283b07cb2',
hash: 'random:9adf270422f525715297afa1649c4ff007a55f09937f57ca628278305624d194',
path: 'sdxl/main/stable-diffusion-xl-1.0-inpainting-0.1',
file_size: 6123456789,
name: 'stable-diffusion-xl-1.0-inpainting-0.1',
base: 'sdxl',
description: 'sdxl main model stable-diffusion-xl-1.0-inpainting-0.1',
Expand Down
Loading