horde-model-reference 2.0.0__tar.gz → 2.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- horde_model_reference-2.1.1/.readthedocs.yaml +28 -0
- {horde_model_reference-2.0.0/src/horde_model_reference.egg-info → horde_model_reference-2.1.1}/PKG-INFO +5 -4
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/README.md +4 -3
- horde_model_reference-2.1.1/docs/legacy_csv_conversion.md +259 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/pyproject.toml +0 -1
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/schemas/stable_diffusion.schema.json +3 -1
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/scripts/get_all_names.py +2 -2
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/scripts/sync/README.md +7 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/__init__.py +14 -1
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/_version.py +2 -2
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/analytics/audit_analysis.py +38 -7
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/analytics/text_model_parser.py +24 -3
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/backends/filesystem_backend.py +402 -50
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/backends/github_backend.py +242 -63
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/integrations/data_merger.py +52 -6
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/integrations/horde_api_models.py +274 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/legacy/classes/legacy_converters.py +130 -15
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/legacy/convert_all_legacy_dbs.py +34 -15
- horde_model_reference-2.1.1/src/horde_model_reference/legacy/text_csv_utils.py +129 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/meta_consts.py +57 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/model_reference_manager.py +605 -68
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/model_reference_metadata.py +10 -2
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/model_reference_records.py +2 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/path_consts.py +49 -13
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/shared.py +2 -1
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/statistics/routers/statistics.py +4 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/v1/routers/references.py +72 -1
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/sync/github_client.py +65 -7
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/sync/legacy_text_validator.py +25 -23
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/sync/watch_mode.py +16 -2
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1/src/horde_model_reference.egg-info}/PKG-INFO +5 -4
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference.egg-info/SOURCES.txt +9 -1
- horde_model_reference-2.1.1/test_endpoint.py +54 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/README.md +6 -73
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/backends/test_primary_mode.py +7 -6
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/conftest.py +77 -29
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/horde_api/conftest.py +2 -29
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/horde_api/test_audit_analysis_live.py +1 -159
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/horde_api/test_audit_worker_count.py +0 -2
- horde_model_reference-2.1.1/tests/integrations/test_stats_aggregation.py +186 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/service/test_v1_api.py +188 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/service/test_v2_api.py +2 -1
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/statistics_and_audit/test_text_model_parser.py +46 -5
- horde_model_reference-2.1.1/tests/test_broken_tutu_grouping.py +215 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/test_canonical_format.py +7 -7
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/test_convert_legacy_database.py +114 -7
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/test_metadata.py +12 -10
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/test_model_reference_manager.py +246 -26
- horde_model_reference-2.1.1/tests/test_text_generation_csv_conversion.py +444 -0
- horde_model_reference-2.1.1/tests/test_text_generation_file_paths.py +209 -0
- horde_model_reference-2.1.1/tests/test_text_model_group.py +157 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/uv.lock +439 -427
- horde_model_reference-2.0.0/tests/horde_api/cassettes/.gitignore +0 -6
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.CONTRIBUTING.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.dockerignore +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.env.example +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.env.primary.example +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.env.sync.example +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.github/workflows/codeql.yml +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.github/workflows/docker-validation.yml +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.github/workflows/lint.yml +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.github/workflows/maintests.yml +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.github/workflows/prtests.yml +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.github/workflows/release.yml +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.gitignore +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.gitmodules +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/.pre-commit-config.yaml +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/DEPLOYMENT.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/Dockerfile +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/LICENSE +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/MANIFEST.in +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docker-compose.redis.yml +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docker-compose.sync.example.yml +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docker-compose.yml +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/build_docs.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/.pages +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/_version.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/backends/.pages +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/backends/base.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/backends/filesystem_backend.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/backends/github_backend.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/backends/http_backend.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/backends/redis_backend.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/backends/replica_backend_base.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/legacy/.pages +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/legacy/classes/.pages +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/legacy/classes/legacy_converters.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/legacy/classes/legacy_models.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/legacy/convert_all_legacy_dbs.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/legacy/validate_sd.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/meta_consts.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/model_reference_manager.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/model_reference_metadata.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/model_reference_records.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/path_consts.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/.pages +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/app.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/shared.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/v1/.pages +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/v1/routers/.pages +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/v1/routers/create_update.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/v1/routers/metadata.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/v1/routers/references.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/v1/routers/shared.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/v2/.pages +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/v2/models.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/v2/routers/.pages +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/v2/routers/metadata.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/service/v2/routers/references.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/showcase/.pages +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/sync/.pages +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/sync/comparator.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/sync/config.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/sync/github_client.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/sync/watch_mode.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/horde_model_reference/util.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/index.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/model_reference_backend.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/primary_deployments.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/replica_backend_base.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/docs/stylesheets/extra.css +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/mkdocs.yml +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/schemas/stable_diffusion.example.json +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/scripts/README.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/scripts/legacy_text/convert.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/scripts/legacy_text/defaults.json +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/scripts/legacy_text/generation_params.json +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/scripts/legacy_text/reverse_convert.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/scripts/sync/github_app_auth_example.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/scripts/sync/sync_github_references.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/setup.cfg +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/analytics/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/analytics/audit_cache.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/analytics/base_cache.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/analytics/constants.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/analytics/filter_presets.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/analytics/statistics.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/analytics/statistics_cache.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/analytics/text_model_grouping.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/backends/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/backends/base.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/backends/http_backend.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/backends/redis_backend.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/backends/replica_backend_base.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/integrations/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/integrations/horde_api_integration.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/legacy/README.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/legacy/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/legacy/classes/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/legacy/classes/legacy_models.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/legacy/validate_sd.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/py.typed +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/app.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/statistics/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/statistics/routers/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/statistics/routers/audit.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/v1/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/v1/routers/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/v1/routers/create_update.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/v1/routers/metadata.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/v1/routers/shared.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/v2/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/v2/models.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/v2/routers/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/v2/routers/metadata.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/service/v2/routers/references.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/showcase/README.md +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/sync/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/sync/comparator.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/sync/config.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/util.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference.egg-info/dependency_links.txt +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference.egg-info/entry_points.txt +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference.egg-info/requires.txt +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference.egg-info/top_level.txt +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/backends/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/backends/test_http_backend.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/backends/test_redis_backend.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/check_model_ref_type_blocks.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/create_env_file_example.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/create_example_json.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/helpers.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/horde_api/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/horde_api/test_data_merger.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/horde_api/test_horde_api_integration.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/horde_api/test_horde_api_integration_live.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/horde_api/test_indexed_horde_types.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/service/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/service/test_replica_backend_base.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/statistics_and_audit/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/statistics_and_audit/test_audit_analysis.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/statistics_and_audit/test_statistics.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/statistics_and_audit/test_statistics_cache.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/statistics_and_audit/test_text_model_grouping.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/sync/__init__.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/sync/test_comparator.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/sync/test_comparator_integration.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/sync/test_config.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/sync/test_legacy_text_validator.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/test_combined_model_statistics.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/test_consts.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/test_converters.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/test_env_example.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/test_examples.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/test_records.py +0 -0
- {horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/tests/test_scripts.py +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Read the Docs configuration file for Sphinx projects
|
|
2
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
|
3
|
+
|
|
4
|
+
# Required
|
|
5
|
+
version: 2
|
|
6
|
+
|
|
7
|
+
# Set the OS, Python version and other tools you might need
|
|
8
|
+
build:
|
|
9
|
+
os: ubuntu-24.04
|
|
10
|
+
tools:
|
|
11
|
+
python: "3.12"
|
|
12
|
+
# You can also specify other tool versions:
|
|
13
|
+
# nodejs: "20"
|
|
14
|
+
# rust: "1.70"
|
|
15
|
+
# golang: "1.20"
|
|
16
|
+
jobs:
|
|
17
|
+
pre_create_environment:
|
|
18
|
+
- asdf plugin add uv
|
|
19
|
+
- asdf install uv latest
|
|
20
|
+
- asdf global uv latest
|
|
21
|
+
create_environment:
|
|
22
|
+
- uv venv "${READTHEDOCS_VIRTUALENV_PATH}"
|
|
23
|
+
install:
|
|
24
|
+
- UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv sync --frozen --group docs
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
mkdocs:
|
|
28
|
+
configuration: mkdocs.yml
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: horde_model_reference
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.1.1
|
|
4
4
|
Summary: A helper library providing a way to work with the lists of generation models, utility models, and any other related files required for the AI-Horde ecosystem.
|
|
5
5
|
Author-email: tazlin <tazlin.on.github@gmail.com>, db0 <mail@dbzer0.com>
|
|
6
6
|
License: GNU AFFERO GENERAL PUBLIC LICENSE
|
|
@@ -964,10 +964,11 @@ print(f"Description: {model['description']}")
|
|
|
964
964
|
|
|
965
965
|
## Documentation
|
|
966
966
|
|
|
967
|
-
- **📖 Full Documentation**: [MkDocs Site](https://
|
|
967
|
+
- **📖 Full Documentation**: [MkDocs Site](https://horde-model-reference.readthedocs.io/en/latest/)
|
|
968
968
|
- **🚀 Deployment Guide**: [DEPLOYMENT.md](DEPLOYMENT.md)
|
|
969
|
-
-
|
|
970
|
-
-
|
|
969
|
+
- **🔄 GitHub Sync (Docker)**: [DOCKER_SYNC.md](DOCKER_SYNC.md) - Optional automated sync to legacy repos
|
|
970
|
+
- **📝 Legacy CSV Conversion**: [docs/legacy_csv_conversion.md](docs/legacy_csv_conversion.md) - Text generation CSV format details
|
|
971
|
+
- **🔧 API Reference**: Run service and visit `http://localhost:19800/docs` for interactive Swagger UI
|
|
971
972
|
- **🤝 Contributing**: [.CONTRIBUTING.md](.CONTRIBUTING.md)
|
|
972
973
|
- **🗂️ Project Structure**:
|
|
973
974
|
- `src/horde_model_reference/` - Core library
|
|
@@ -270,10 +270,11 @@ print(f"Description: {model['description']}")
|
|
|
270
270
|
|
|
271
271
|
## Documentation
|
|
272
272
|
|
|
273
|
-
- **📖 Full Documentation**: [MkDocs Site](https://
|
|
273
|
+
- **📖 Full Documentation**: [MkDocs Site](https://horde-model-reference.readthedocs.io/en/latest/)
|
|
274
274
|
- **🚀 Deployment Guide**: [DEPLOYMENT.md](DEPLOYMENT.md)
|
|
275
|
-
-
|
|
276
|
-
-
|
|
275
|
+
- **🔄 GitHub Sync (Docker)**: [DOCKER_SYNC.md](DOCKER_SYNC.md) - Optional automated sync to legacy repos
|
|
276
|
+
- **📝 Legacy CSV Conversion**: [docs/legacy_csv_conversion.md](docs/legacy_csv_conversion.md) - Text generation CSV format details
|
|
277
|
+
- **🔧 API Reference**: Run service and visit `http://localhost:19800/docs` for interactive Swagger UI
|
|
277
278
|
- **🤝 Contributing**: [.CONTRIBUTING.md](.CONTRIBUTING.md)
|
|
278
279
|
- **🗂️ Project Structure**:
|
|
279
280
|
- `src/horde_model_reference/` - Core library
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# Legacy CSV Conversion for Text Generation Models
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The `text_generation` category is unique in the model reference system as it's the **only category** that uses CSV format for legacy files instead of JSON. This document explains the conversion process, common pitfalls, and implementation details.
|
|
6
|
+
|
|
7
|
+
## File Format Summary
|
|
8
|
+
|
|
9
|
+
| Category | Legacy Format | V2 Format | Legacy Path | V2 Path |
|
|
10
|
+
|----------|---------------|-----------|-------------|---------|
|
|
11
|
+
| `text_generation` | **CSV** | JSON | `{base}/legacy/models.csv` | `{base}/text_generation.json` |
|
|
12
|
+
| All others | JSON | JSON | `{base}/legacy/{category}.json` | `{base}/{category}.json` |
|
|
13
|
+
|
|
14
|
+
## CSV Structure
|
|
15
|
+
|
|
16
|
+
The legacy CSV file (`models.csv`) has the following columns:
|
|
17
|
+
|
|
18
|
+
```csv
|
|
19
|
+
name,parameters_bn,description,version,style,nsfw,baseline,url,tags,settings,display_name
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Column Details
|
|
23
|
+
|
|
24
|
+
- **name**: Model identifier (string)
|
|
25
|
+
- **parameters_bn**: Parameters in billions (float, e.g., "7.0" for 7B parameters)
|
|
26
|
+
- **description**: Model description (string)
|
|
27
|
+
- **version**: Model version (string)
|
|
28
|
+
- **style**: Model style/category (string)
|
|
29
|
+
- **nsfw**: NSFW flag (string: "true" or "false")
|
|
30
|
+
- **baseline**: Base model/architecture (string)
|
|
31
|
+
- **url**: Model URL (string)
|
|
32
|
+
- **tags**: Comma-separated tags (string, e.g., "tag1,tag2,tag3")
|
|
33
|
+
- **settings**: JSON object as string (string, e.g., '{"temperature": 0.7}')
|
|
34
|
+
- **display_name**: Display name (string)
|
|
35
|
+
|
|
36
|
+
## Conversion Process
|
|
37
|
+
|
|
38
|
+
### 1. CSV → Internal Dictionary
|
|
39
|
+
|
|
40
|
+
The `LegacyTextGenerationConverter._load_and_validate_legacy_records()` method reads the CSV and converts it to an internal dictionary format:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
# Parameters: billions → integer
|
|
44
|
+
params_bn = float(row.get("parameters_bn", 0))
|
|
45
|
+
parameters = int(params_bn * 1_000_000_000) # 7.0 → 7,000,000,000
|
|
46
|
+
|
|
47
|
+
# Tags: comma-separated string → list
|
|
48
|
+
tags_str = row.get("tags", "")
|
|
49
|
+
tags = [t.strip() for t in tags_str.split(",") if t.strip()]
|
|
50
|
+
|
|
51
|
+
# Settings: JSON string → dict
|
|
52
|
+
settings_str = row.get("settings", "")
|
|
53
|
+
settings = json.loads(settings_str) if settings_str else None
|
|
54
|
+
|
|
55
|
+
# NSFW: string → boolean
|
|
56
|
+
nsfw = row.get("nsfw", "").lower() == "true"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 2. Dictionary → Pydantic Validation
|
|
60
|
+
|
|
61
|
+
The internal dictionary is validated using `LegacyTextGenerationRecord` Pydantic model.
|
|
62
|
+
|
|
63
|
+
### 3. Pydantic → V2 JSON Output
|
|
64
|
+
|
|
65
|
+
The base class `write_out_records()` method writes the converted records to `text_generation.json` (always JSON format).
|
|
66
|
+
|
|
67
|
+
### Backend Prefix Filtering
|
|
68
|
+
|
|
69
|
+
`LegacyTextGenerationConverter._convert_single_record()` calls `has_legacy_text_backend_prefix()` and drops any rows whose `name` uses backend-generated prefixes such as `aphrodite/` or `koboldcpp/`. These prefixed entries are duplicates that only exist for backwards compatibility and are intentionally excluded from the v2 dataset.
|
|
70
|
+
|
|
71
|
+
## Critical Constraints
|
|
72
|
+
|
|
73
|
+
### Settings Field Type Limitation
|
|
74
|
+
|
|
75
|
+
The `settings` field has a strict type constraint that **does NOT support nested dictionaries**:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
settings: dict[str, int | float | str | list[int] | list[float] | list[str] | bool] | None
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Valid Settings:**
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"temperature": 0.7,
|
|
86
|
+
"top_p": 0.9,
|
|
87
|
+
"max_tokens": 2048,
|
|
88
|
+
"stop_sequences": ["</s>", "[DONE]"],
|
|
89
|
+
"enabled": true
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Invalid Settings (will fail validation):**
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"nested": {"key": "value"}, // ❌ Nested dicts not allowed
|
|
98
|
+
"complex": {"another": {"level": "here"}} // ❌ Nested dicts not allowed
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Settings JSON Validity
|
|
103
|
+
|
|
104
|
+
The `settings` column must contain valid JSON. If a row includes malformed JSON, `json.loads()` raises `json.JSONDecodeError` and the converter stops rather than silently skipping that entry.
|
|
105
|
+
|
|
106
|
+
### Numeric Parameters Required
|
|
107
|
+
|
|
108
|
+
`parameters_bn` must parse as a floating-point number (e.g., `"7.0"`). Non-numeric strings—including blank cells—raise a `ValueError` during conversion; there is no automatic fallback beyond the explicit `0` default used when the column is truly missing.
|
|
109
|
+
|
|
110
|
+
## Common Pitfalls
|
|
111
|
+
|
|
112
|
+
### 1. Double Legacy Folder Bug
|
|
113
|
+
|
|
114
|
+
**Problem:** Passing the wrong path to converters results in `{base}/legacy/legacy/models.csv`.
|
|
115
|
+
|
|
116
|
+
**Root Cause:** The converter's `legacy_folder_path` parameter expects a BASE path (e.g., `data/`), and it automatically appends `/legacy/` internally via `get_legacy_model_reference_file_path()`.
|
|
117
|
+
|
|
118
|
+
**Wrong Usage:**
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
# ❌ WRONG - results in data/legacy/legacy/models.csv
|
|
122
|
+
converter = LegacyTextGenerationConverter(
|
|
123
|
+
legacy_folder_path=Path("data/legacy"), # Already has /legacy/
|
|
124
|
+
target_file_folder=Path("data"),
|
|
125
|
+
)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Correct Usage:**
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
# ✅ CORRECT - results in data/legacy/models.csv
|
|
132
|
+
converter = LegacyTextGenerationConverter(
|
|
133
|
+
legacy_folder_path=Path("data"), # Base path only
|
|
134
|
+
target_file_folder=Path("data"),
|
|
135
|
+
)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 2. Empty File Handling
|
|
139
|
+
|
|
140
|
+
Empty CSV files (0 bytes or only headers) are handled gracefully and return an empty dictionary without errors.
|
|
141
|
+
|
|
142
|
+
### 3. Missing Optional Fields
|
|
143
|
+
|
|
144
|
+
CSV rows with missing optional fields are handled by using empty strings or default values:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
# Missing fields default to:
|
|
148
|
+
description=""
|
|
149
|
+
version=""
|
|
150
|
+
style=""
|
|
151
|
+
baseline=""
|
|
152
|
+
url=""
|
|
153
|
+
tags=[]
|
|
154
|
+
settings=None
|
|
155
|
+
display_name=""
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`parameters_bn` is the exception—leave it blank or non-numeric and the conversion fails. Ensure every row contains a numeric value (use `0` when no parameter estimate is available).
|
|
159
|
+
|
|
160
|
+
## Testing Considerations
|
|
161
|
+
|
|
162
|
+
### Test Fixture Path Handling
|
|
163
|
+
|
|
164
|
+
In tests, the `populated_legacy_path` fixture creates files in `primary/legacy/` but when calling converters, always pass `primary_base` (not `populated_legacy_path`):
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
# ✅ CORRECT
|
|
168
|
+
def test_converter(primary_base: Path, populated_legacy_path: Path):
|
|
169
|
+
converter = LegacyTextGenerationConverter(
|
|
170
|
+
legacy_folder_path=primary_base, # Pass base, not populated_legacy_path
|
|
171
|
+
target_file_folder=primary_base,
|
|
172
|
+
)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Comprehensive Test Coverage
|
|
176
|
+
|
|
177
|
+
The test suite (`test_text_generation_csv_conversion.py`) covers:
|
|
178
|
+
|
|
179
|
+
1. CSV reading and parsing
|
|
180
|
+
2. JSON output format verification (regression test)
|
|
181
|
+
3. Data integrity (all fields preserved)
|
|
182
|
+
4. Empty file handling
|
|
183
|
+
5. Missing optional fields
|
|
184
|
+
6. Complex settings (within type constraints)
|
|
185
|
+
7. Non-existent file handling
|
|
186
|
+
8. Large parameter value conversion
|
|
187
|
+
9. Output format verification (JSON not CSV)
|
|
188
|
+
|
|
189
|
+
## Implementation Details
|
|
190
|
+
|
|
191
|
+
### Key Files
|
|
192
|
+
|
|
193
|
+
- **Converter**: `src/horde_model_reference/legacy/classes/legacy_converters.py`
|
|
194
|
+
- `LegacyTextGenerationConverter` class
|
|
195
|
+
- `_load_and_validate_legacy_records()` override for CSV reading
|
|
196
|
+
- `_convert_single_record()` skips backend-prefixed duplicates via `has_legacy_text_backend_prefix()`
|
|
197
|
+
|
|
198
|
+
- **Backend - GitHub**: `src/horde_model_reference/backends/github_backend.py`
|
|
199
|
+
- `_read_legacy_csv_to_dict()` method for CSV parsing
|
|
200
|
+
- Empty file handling
|
|
201
|
+
|
|
202
|
+
- **Backend - FileSystem**: `src/horde_model_reference/backends/filesystem_backend.py`
|
|
203
|
+
- `_read_legacy_csv_to_dict()` method for CSV parsing
|
|
204
|
+
|
|
205
|
+
- **Tests**:
|
|
206
|
+
- `tests/test_text_generation_csv_conversion.py` - Comprehensive CSV conversion tests
|
|
207
|
+
- `tests/test_text_generation_file_paths.py` - File path and format verification
|
|
208
|
+
- `tests/conftest.py` - Test fixtures with CSV generation
|
|
209
|
+
|
|
210
|
+
### Parameter Conversion Formula
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
# CSV stores parameters in billions (float)
|
|
214
|
+
parameters_bn = 7.0 # From CSV
|
|
215
|
+
|
|
216
|
+
# Convert to integer parameters
|
|
217
|
+
parameters = int(parameters_bn * 1_000_000_000)
|
|
218
|
+
# Result: 7,000,000,000
|
|
219
|
+
|
|
220
|
+
# Examples:
|
|
221
|
+
# 0.5 → 500,000,000 (500M)
|
|
222
|
+
# 7.0 → 7,000,000,000 (7B)
|
|
223
|
+
# 13.0 → 13,000,000,000 (13B)
|
|
224
|
+
# 70.0 → 70,000,000,000 (70B)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Best Practices
|
|
228
|
+
|
|
229
|
+
1. **Always pass base paths** to converters, never paths with `/legacy/` already included
|
|
230
|
+
2. **Test with empty files** to ensure graceful handling
|
|
231
|
+
3. **Validate settings constraints** - only flat dicts allowed
|
|
232
|
+
4. **Pre-validate numeric and JSON fields** - ensure `parameters_bn` values are numeric strings and `settings` cells contain valid JSON before running the converter
|
|
233
|
+
5. **Use CSV.DictWriter** for creating test CSV files to ensure proper formatting
|
|
234
|
+
6. **Verify JSON output** - output should always be JSON, never CSV
|
|
235
|
+
7. **Handle missing fields** with appropriate defaults
|
|
236
|
+
|
|
237
|
+
## GitHub Sync Behavior
|
|
238
|
+
|
|
239
|
+
When syncing from GitHub:
|
|
240
|
+
|
|
241
|
+
1. GitHub backend downloads `legacy/models.csv` (CSV format)
|
|
242
|
+
2. If file is empty (0 bytes), skip conversion
|
|
243
|
+
3. Parse CSV using `_read_legacy_csv_to_dict()`
|
|
244
|
+
4. Convert to TextGenerationModelRecord objects
|
|
245
|
+
5. Write to `text_generation.json` (JSON format)
|
|
246
|
+
6. Serve both legacy CSV and v2 JSON endpoints
|
|
247
|
+
|
|
248
|
+
## Migration Notes
|
|
249
|
+
|
|
250
|
+
If you need to add a new category with CSV format (not recommended unless necessary):
|
|
251
|
+
|
|
252
|
+
1. Override `_load_and_validate_legacy_records()` in your converter
|
|
253
|
+
2. Implement CSV reading logic similar to `LegacyTextGenerationConverter`
|
|
254
|
+
3. Add backend CSV reading support in GitHub and FileSystem backends
|
|
255
|
+
4. Create comprehensive tests covering all edge cases
|
|
256
|
+
5. Update path constants if using different filenames
|
|
257
|
+
6. Document the CSV structure and conversion process
|
|
258
|
+
|
|
259
|
+
**Note:** It's strongly recommended to use JSON for new categories to maintain consistency with the rest of the system.
|
|
@@ -5,7 +5,7 @@ from loguru import logger
|
|
|
5
5
|
|
|
6
6
|
logger.remove()
|
|
7
7
|
|
|
8
|
-
from horde_model_reference import MODEL_REFERENCE_CATEGORY, ModelReferenceManager # noqa: E402
|
|
8
|
+
from horde_model_reference import MODEL_REFERENCE_CATEGORY, ModelReferenceManager, PrefetchStrategy # noqa: E402
|
|
9
9
|
|
|
10
10
|
ALIASES = {"stable_diffusion": "image_generation"}
|
|
11
11
|
|
|
@@ -22,7 +22,7 @@ def configure_logger(quiet: bool) -> None:
|
|
|
22
22
|
def get_all_names(model_reference_category: MODEL_REFERENCE_CATEGORY, refresh: bool) -> list[str]:
|
|
23
23
|
"""Get all model names for a given model reference category."""
|
|
24
24
|
logger.debug(f"Getting all names for category: {model_reference_category}")
|
|
25
|
-
model_reference_manager = ModelReferenceManager(
|
|
25
|
+
model_reference_manager = ModelReferenceManager(prefetch_strategy=PrefetchStrategy.SYNC)
|
|
26
26
|
all_references = model_reference_manager.get_all_model_references(overwrite_existing=refresh)
|
|
27
27
|
|
|
28
28
|
if model_reference_category not in all_references:
|
|
@@ -61,6 +61,13 @@ PRIMARY (v1 API) ────► Comparator ◄──── GitHub (legacy repos
|
|
|
61
61
|
## Important Notes
|
|
62
62
|
|
|
63
63
|
- Ensure your environment variables are set correctly before running the sync service.
|
|
64
|
+
- **Git Identity Configuration**: The user running the sync service must have git identity configured for commits to work:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
git config --global user.name "Your Name"
|
|
68
|
+
git config --global user.email "your.email@example.com"
|
|
69
|
+
```
|
|
70
|
+
|
|
64
71
|
- **If running the sync service on the same host as the PRIMARY instance**
|
|
65
72
|
- You must set a different `AIWORKER_CACHE_HOME` for each or it will never detect changes. You should always set this variable when using the sync service.
|
|
66
73
|
|
{horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/__init__.py
RENAMED
|
@@ -269,6 +269,18 @@ Only used in PRIMARY mode. If True, will download and convert legacy references
|
|
|
269
269
|
"""Percentage threshold for low usage flag in audit analysis. Default 0.0065% flags bottom ~10% of models. \
|
|
270
270
|
Set lower (e.g., 0.005%) to flag fewer models or higher (e.g., 0.01%) to flag more models."""
|
|
271
271
|
|
|
272
|
+
text_gen_low_usage_threshold_percentage: float = 0.02
|
|
273
|
+
"""Low usage threshold for text_generation models (2% - more lenient than image models at 0.65%)."""
|
|
274
|
+
|
|
275
|
+
text_gen_ignore_download_hosts: bool = True
|
|
276
|
+
"""Skip download host validation for text_generation models completely."""
|
|
277
|
+
|
|
278
|
+
text_gen_critical_usage_threshold: int = 10
|
|
279
|
+
"""Minimum monthly usage for text_generation to be flagged as critical (allows some usage)."""
|
|
280
|
+
|
|
281
|
+
text_gen_critical_worker_threshold: int = 1
|
|
282
|
+
"""Minimum worker count for text_generation to be flagged as critical (allows some workers)."""
|
|
283
|
+
|
|
272
284
|
@model_validator(mode="after")
|
|
273
285
|
def validate_mode_configuration(self) -> HordeModelReferenceSettings:
|
|
274
286
|
"""Validate that settings are appropriate for the configured replication mode."""
|
|
@@ -349,7 +361,7 @@ from .path_consts import ( # noqa: E402
|
|
|
349
361
|
horde_model_reference_paths,
|
|
350
362
|
)
|
|
351
363
|
|
|
352
|
-
from .model_reference_manager import ModelReferenceManager # noqa: E402
|
|
364
|
+
from .model_reference_manager import ModelReferenceManager, PrefetchStrategy # noqa: E402
|
|
353
365
|
|
|
354
366
|
__all__ = [
|
|
355
367
|
"BASE_PATH",
|
|
@@ -363,6 +375,7 @@ __all__ = [
|
|
|
363
375
|
"MODEL_STYLE",
|
|
364
376
|
"ModelClassification",
|
|
365
377
|
"ModelReferenceManager",
|
|
378
|
+
"PrefetchStrategy",
|
|
366
379
|
"get_model_reference_file_path",
|
|
367
380
|
"get_model_reference_filename",
|
|
368
381
|
"horde_model_reference_paths",
|
{horde_model_reference-2.0.0 → horde_model_reference-2.1.1}/src/horde_model_reference/_version.py
RENAMED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = 'v2.
|
|
32
|
-
__version_tuple__ = version_tuple = (2,
|
|
31
|
+
__version__ = version = 'v2.1.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 1, 1)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -123,16 +123,25 @@ class FlagValidatorService:
|
|
|
123
123
|
def validate_downloads(
|
|
124
124
|
downloads: list[Any] | None,
|
|
125
125
|
preferred_hosts: list[str] | None = None,
|
|
126
|
+
category: MODEL_REFERENCE_CATEGORY | None = None,
|
|
126
127
|
) -> tuple[bool, bool, bool, bool]:
|
|
127
128
|
"""Validate download URLs and return related flags.
|
|
128
129
|
|
|
129
130
|
Args:
|
|
130
131
|
downloads: List of download records to validate.
|
|
131
132
|
preferred_hosts: List of preferred file hosts. If None, uses settings.
|
|
133
|
+
category: Model category - if text_generation and ignore setting is True, returns all False.
|
|
132
134
|
|
|
133
135
|
Returns:
|
|
134
136
|
Tuple of (no_download_urls, has_multiple_hosts, has_non_preferred_host, has_unknown_host)
|
|
135
137
|
"""
|
|
138
|
+
# Skip download validation for text_generation if configured
|
|
139
|
+
if (
|
|
140
|
+
category == MODEL_REFERENCE_CATEGORY.text_generation
|
|
141
|
+
and horde_model_reference_settings.text_gen_ignore_download_hosts
|
|
142
|
+
):
|
|
143
|
+
return (False, False, False, False)
|
|
144
|
+
|
|
136
145
|
if preferred_hosts is None:
|
|
137
146
|
preferred_hosts = horde_model_reference_settings.preferred_file_hosts
|
|
138
147
|
|
|
@@ -195,6 +204,7 @@ class FlagValidatorService:
|
|
|
195
204
|
statistics: CombinedModelStatistics | None,
|
|
196
205
|
category_total_usage: int,
|
|
197
206
|
low_usage_threshold: float | None = None,
|
|
207
|
+
category: MODEL_REFERENCE_CATEGORY | None = None,
|
|
198
208
|
) -> tuple[bool, bool, bool, bool, bool]:
|
|
199
209
|
"""Validate Horde API statistics and usage data.
|
|
200
210
|
|
|
@@ -202,6 +212,7 @@ class FlagValidatorService:
|
|
|
202
212
|
statistics: Optional Horde API statistics.
|
|
203
213
|
category_total_usage: Total monthly usage for the category.
|
|
204
214
|
low_usage_threshold: Percentage threshold for low usage. If None, uses settings default.
|
|
215
|
+
category: Model category for category-specific thresholds.
|
|
205
216
|
|
|
206
217
|
Returns:
|
|
207
218
|
Tuple of (zero_usage_day, zero_usage_month, zero_usage_total, no_active_workers, low_usage)
|
|
@@ -209,9 +220,12 @@ class FlagValidatorService:
|
|
|
209
220
|
if not statistics:
|
|
210
221
|
return (False, False, False, False, False)
|
|
211
222
|
|
|
212
|
-
# Use
|
|
223
|
+
# Use category-specific threshold for text_generation
|
|
213
224
|
if low_usage_threshold is None:
|
|
214
|
-
|
|
225
|
+
if category == MODEL_REFERENCE_CATEGORY.text_generation:
|
|
226
|
+
low_usage_threshold = horde_model_reference_settings.text_gen_low_usage_threshold_percentage
|
|
227
|
+
else:
|
|
228
|
+
low_usage_threshold = horde_model_reference_settings.low_usage_threshold_percentage
|
|
215
229
|
|
|
216
230
|
# Check for zero workers
|
|
217
231
|
no_active_workers = statistics.worker_count == 0
|
|
@@ -422,11 +436,16 @@ class ModelAuditInfo(BaseModel):
|
|
|
422
436
|
def is_critical(self) -> bool:
|
|
423
437
|
"""Determine if model is in critical state.
|
|
424
438
|
|
|
425
|
-
|
|
439
|
+
For text_generation: usage_month < threshold AND worker_count < threshold
|
|
440
|
+
For other models: zero month usage AND no active workers (original logic)
|
|
426
441
|
|
|
427
442
|
Returns:
|
|
428
443
|
True if model meets critical criteria.
|
|
429
444
|
"""
|
|
445
|
+
if self.category == MODEL_REFERENCE_CATEGORY.text_generation:
|
|
446
|
+
usage_threshold = horde_model_reference_settings.text_gen_critical_usage_threshold
|
|
447
|
+
worker_threshold = horde_model_reference_settings.text_gen_critical_worker_threshold
|
|
448
|
+
return self.usage_month < usage_threshold and self.worker_count < worker_threshold
|
|
430
449
|
return self.deletion_risk_flags.zero_usage_month and self.deletion_risk_flags.no_active_workers
|
|
431
450
|
|
|
432
451
|
@computed_field # type: ignore[prop-decorator]
|
|
@@ -632,10 +651,16 @@ class ImageGenerationDeletionRiskFlagsHandler(DeletionRiskFlagsHandler):
|
|
|
632
651
|
|
|
633
652
|
return (
|
|
634
653
|
DeletionRiskFlagsBuilder()
|
|
635
|
-
.with_download_flags(
|
|
654
|
+
.with_download_flags(
|
|
655
|
+
*FlagValidatorService.validate_downloads(downloads, category=MODEL_REFERENCE_CATEGORY.image_generation)
|
|
656
|
+
)
|
|
636
657
|
.with_missing_description(FlagValidatorService.validate_description(model_record.description))
|
|
637
658
|
.with_missing_baseline(FlagValidatorService.validate_baseline(model_record.baseline))
|
|
638
|
-
.with_statistics_flags(
|
|
659
|
+
.with_statistics_flags(
|
|
660
|
+
*FlagValidatorService.validate_statistics(
|
|
661
|
+
statistics, category_total_usage, category=MODEL_REFERENCE_CATEGORY.image_generation
|
|
662
|
+
)
|
|
663
|
+
)
|
|
639
664
|
.build()
|
|
640
665
|
)
|
|
641
666
|
|
|
@@ -697,10 +722,16 @@ class TextGenerationDeletionRiskFlagsHandler(DeletionRiskFlagsHandler):
|
|
|
697
722
|
|
|
698
723
|
return (
|
|
699
724
|
DeletionRiskFlagsBuilder()
|
|
700
|
-
.with_download_flags(
|
|
725
|
+
.with_download_flags(
|
|
726
|
+
*FlagValidatorService.validate_downloads(downloads, category=MODEL_REFERENCE_CATEGORY.text_generation)
|
|
727
|
+
)
|
|
701
728
|
.with_missing_description(FlagValidatorService.validate_description(model_record.description))
|
|
702
729
|
.with_missing_baseline(FlagValidatorService.validate_baseline(model_record.baseline))
|
|
703
|
-
.with_statistics_flags(
|
|
730
|
+
.with_statistics_flags(
|
|
731
|
+
*FlagValidatorService.validate_statistics(
|
|
732
|
+
statistics, category_total_usage, category=MODEL_REFERENCE_CATEGORY.text_generation
|
|
733
|
+
)
|
|
734
|
+
)
|
|
704
735
|
.build()
|
|
705
736
|
)
|
|
706
737
|
|
|
@@ -49,7 +49,9 @@ VARIANT_PATTERNS = [
|
|
|
49
49
|
|
|
50
50
|
# Quantization patterns
|
|
51
51
|
QUANT_PATTERNS = [
|
|
52
|
-
r"\b(Q[2-8]
|
|
52
|
+
r"\b(Q[2-8]_K(?:_[SMLH])?)\b", # Q4_K_M, Q5_K_S, Q6_K (K-quants with optional size)
|
|
53
|
+
r"\b(Q[2-8]_[01])\b", # Q4_0, Q5_0, Q5_1, Q8_0 (legacy/standard quants)
|
|
54
|
+
r"\b(Q[2-8])\b", # Q4, Q8 (bare quant indicators)
|
|
53
55
|
r"\b(GGUF|GGML|GPTQ|AWQ|EXL2)\b",
|
|
54
56
|
r"\b(fp16|fp32|int8|int4)\b",
|
|
55
57
|
]
|
|
@@ -185,9 +187,22 @@ def normalize_model_name(model_name: str) -> str:
|
|
|
185
187
|
return normalized.strip("_")
|
|
186
188
|
|
|
187
189
|
|
|
190
|
+
@dataclass
|
|
191
|
+
class TextModelGroup:
|
|
192
|
+
"""Represents a group of text model variants sharing the same base model.
|
|
193
|
+
|
|
194
|
+
Attributes:
|
|
195
|
+
base_name: The base model name.
|
|
196
|
+
variants: List of full model names that are variants of the base model.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
base_name: str
|
|
200
|
+
variants: list[str]
|
|
201
|
+
|
|
202
|
+
|
|
188
203
|
def group_text_models_by_base(
|
|
189
204
|
model_names: list[str],
|
|
190
|
-
) -> dict[str,
|
|
205
|
+
) -> dict[str, TextModelGroup]:
|
|
191
206
|
"""Group text model names by their base model.
|
|
192
207
|
|
|
193
208
|
Groups variants of the same model together based on extracted base names.
|
|
@@ -224,7 +239,13 @@ def group_text_models_by_base(
|
|
|
224
239
|
|
|
225
240
|
logger.debug(f"Grouped {len(model_names)} models into {len(grouped)} base models")
|
|
226
241
|
|
|
227
|
-
return
|
|
242
|
+
return {
|
|
243
|
+
base_name: TextModelGroup(
|
|
244
|
+
base_name=base_name,
|
|
245
|
+
variants=variants,
|
|
246
|
+
)
|
|
247
|
+
for base_name, variants in grouped.items()
|
|
248
|
+
}
|
|
228
249
|
|
|
229
250
|
|
|
230
251
|
@lru_cache(maxsize=2048)
|