feat!: modernize toolchain and replace apple/ml-stable-diffusion with native diffusers conversion (#58)
* feat(deps): support ComfyUI's numpy 2 toolchain; make conversion optional The runtime package now installs and runs under numpy 2 / coremltools 9 / torch 2.7 — matching current ComfyUI — without apple/ml-stable-diffusion. - Drop the heavy converter stack (ml-stable-diffusion, diffusers, peft, omegaconf, overrides, transformers) from runtime dependencies; require numpy>=2. - Vendor the runtime pieces: a slim CoreMLModel wrapper around coremltools and the attention-implementation constants. - Lazy-import the converters; the Convert nodes raise a clear error when the legacy conversion dependencies are absent. Loading and sampling existing Core ML models no longer needs them. - CI: Tier 0 tracks the numpy 2 / torch 2.7 toolchain; drop the Tier 2 golden-image lane (it converts at runtime, which now requires the legacy stack) and its fixtures. * feat(conversion): replace apple/ml-stable-diffusion with native diffusers path Reimplement Core ML UNet conversion on top of diffusers instead of the apple/ml-stable-diffusion git dependency, so the full suite (including conversion) installs through ComfyUI Manager without extras on the NumPy 2 toolchain. - Add coreml_suite/conversion package: split-einsum attention processors, a conv2d output-shape helper, Transformer2D trace patches, and a UNet input-adapter wrapper preserving the historical Core ML I/O contract. - Drop python_coreml_stable_diffusion and overrides; route SD15, SDXL, SDXL refiner, and LCM conversion through diffusers UNet2DConditionModel. - Declare diffusers, peft, omegaconf, and transformers as runtime deps. - Add characterization tests asserting split-einsum matches reference attention math; extend the synthetic-UNet smoke test for the wrapper. - Bump to 1.1.0 and set requires-comfyui to a semver constraint (>=0.3.27) so the Comfy Registry publish succeeds. * refactor(conversion)!: native diffusers context layout; drop legacy fallbacks Address PR review feedback: - Drop the legacy converter ImportError fallbacks and LEGACY_CONVERTER_MODULES guards in nodes.py and lcm/nodes.py. Conversion dependencies are mandatory in pyproject, so the indirection is dead code. - Tier 0 CI resolves its toolchain from pyproject via uv (uv sync + uv run) instead of hand-pinned pip installs, removing duplicated version maintenance. - Document the conversion lineage: credit apple/ml-stable-diffusion as the origin, note the implementation has diverged to a native diffusers path, and state the intent to iterate independently. Fix stale README links that pointed users to apple/ml-stable-diffusion for conversion. - Drop the unused `sources` argument from CoreMLModel. BREAKING CHANGE: the converted Core ML UNet now takes encoder_hidden_states in the native diffusers layout (batch, tokens, hidden) instead of (batch, hidden, 1, tokens). This removes the boundary transposes in CoreMLUNetWrapper and CoreMLInputs. Core ML models converted with earlier versions are incompatible and must be re-converted. Bump to 2.0.0. * test: widen split-einsum allclose tolerance for cross-platform float drift The split-einsum attention reorders float32 reductions relative to the reference, so equality holds only up to rounding. The default allclose atol (1e-8) is too tight on Linux x86 BLAS and failed Tier 0 CI; use atol=1e-6 to match the existing chunked-path characterization test. * ci: run macOS smoke tier on the self-hosted Apple Silicon runner GitHub-hosted macOS carries a 10x minute multiplier and exhausts the included Actions minutes too quickly. Move the Tier 1 smoke job onto the self-hosted Apple Silicon runner ([self-hosted, macOS, ARM64, coreml]) so macOS coverage no longer consumes hosted minutes. Tier 0 stays on hosted ubuntu (1x). * ci: fix uv setup for both tiers astral-sh/setup-uv@v3 was retagged and its old commit garbage-collected, so codeload 404s when Actions resolves the stale SHA. Bump Tier 0 (ubuntu) to setup-uv@v7, and drop the action entirely from Tier 1 since the self-hosted runner already provides uv. * test(ci): restore golden-image correctness gate on the self-hosted runner The Tier 2 end-to-end correctness check (real SD1.5 -> Core ML -> image, gated on SHA/PSNR vs a golden) was dropped during the modernization. With the breaking 3D-context change, the synthetic smoke and shape/attention characterization tests no longer cover real-model conversion correctness. Restore tier2.yml (on the [self-hosted, macOS, ARM64, coreml] runner shared with Tier 1), the golden-image test, and the e2e workflow. Adapt the pinned ComfyUI resolution to the requires-comfyui semver tag (vX.Y.Z) instead of a commit SHA, and re-register the m2 marker. The golden is intentionally not committed: the first self-hosted run regenerates it under the new 3D contract and fails for review, per the test's documented bootstrap. * test(ci): add golden image for SD1.5 seed 42 under the 3D-context contract Generated by the first Tier 2 self-hosted run after the native diffusers conversion change. The decoded image is a coherent SD1.5 generation, confirming the (batch, tokens, hidden) Core ML contract produces correct output end-to-end. Subsequent runs gate on this golden (SHA-strict, PSNR fallback). * test(ci): force fresh conversion in Tier 2; drop stale golden The converter skips conversion when a same-named model already exists, keyed on conversion parameters but not the conversion code/toolchain. The self-hosted runner held a pre-existing v1-5 .mlmodelc (4D-context, old toolchain), so the Tier 2 runs reused it (~8-30s) instead of converting — the gate validated a stale model, not the new native diffusers path. Purge the cached Core ML UNets before running so every Tier 2 run does a real convert -> compile -> sample. Drop the golden generated from the stale cache; the next run regenerates it from a genuine 3D-contract conversion and fails for review. * test(ci): add golden image from a genuine 3D-contract conversion Regenerated by a Tier 2 run with the model cache purged, so the converter actually ran (62s, not a cache hit). The fresh model exposes the new 3D encoder_hidden_states input [1, 77, 768], and its decoded SD1.5 seed-42 image is byte-identical to the prior baseline — confirming the native diffusers conversion is behavior-preserving end to end.
This commit is contained in:
@@ -5,10 +5,10 @@ on:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
# Minimal-deps run: Tier 0 must work without ComfyUI, coremltools, or
|
||||
# python_coreml_stable_diffusion (Linux CI image won't have them). The
|
||||
# in-tree purity gate (tests/unit/test_tier0_purity.py) double-checks
|
||||
# that the suite hasn't started leaking framework imports.
|
||||
# Deps are resolved from pyproject.toml via uv, so the toolchain pins live in
|
||||
# one place. Tier 0 must run without ComfyUI; the in-tree purity gate
|
||||
# (tests/unit/test_tier0_purity.py) enforces that the suite hasn't started
|
||||
# leaking framework imports.
|
||||
jobs:
|
||||
unit:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -16,18 +16,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
python-version: "3.11"
|
||||
enable-cache: true
|
||||
|
||||
- name: Install Tier 0 deps
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
# Tier 0 only needs torch + numpy + pytest; everything else
|
||||
# is Mac-only.
|
||||
python -m pip install \
|
||||
"torch==2.0.1" "numpy<1.25" \
|
||||
"pytest>=8" "pytest-xdist"
|
||||
- name: uv sync
|
||||
run: uv sync --no-install-project
|
||||
|
||||
- name: Run Tier 0
|
||||
run: pytest -m unit tests/ -v
|
||||
run: uv run pytest -m unit tests/ -v
|
||||
|
||||
@@ -1,29 +1,21 @@
|
||||
name: Tier 1 — Smoke (macOS-ARM)
|
||||
name: Tier 1 — Smoke (macOS self-hosted)
|
||||
|
||||
# macOS smoke tests run on the self-hosted Apple Silicon runner instead of
|
||||
# GitHub-hosted macOS (10x minute multiplier), which exhausts the included
|
||||
# Actions minutes too quickly.
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
# Gate behind the run-tier1 label too, so external PRs that touch
|
||||
# only docs don't burn a minute of macOS-ARM time. Maintainers can
|
||||
# always re-run via the run-tier1 label.
|
||||
types: [opened, synchronize, reopened, labeled]
|
||||
|
||||
jobs:
|
||||
smoke:
|
||||
if: |
|
||||
github.event_name == 'push' ||
|
||||
github.event.action != 'labeled' ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-tier1')
|
||||
runs-on: macos-14 # M1, Apple Silicon hosted runner
|
||||
runs-on: [self-hosted, macOS, ARM64, coreml]
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
enable-cache: true
|
||||
|
||||
# The self-hosted runner provides uv; no setup-uv action needed.
|
||||
- name: uv sync
|
||||
run: uv sync --no-install-project
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
# Hybrid ComfyUI strategy:
|
||||
# - schedule (nightly) -> latest origin/master + ComfyUI's own
|
||||
# requirements.txt (constrained). Canary for upstream API breakage.
|
||||
# - PR label / dispatch -> the pinned requires-comfyui SHA + the frozen
|
||||
# - PR label / dispatch -> the requires-comfyui version tag + the frozen
|
||||
# `comfy` uv group. Reproducible merge gate, immune to overnight drift.
|
||||
- name: Resolve ComfyUI ref + mode
|
||||
run: |
|
||||
@@ -38,10 +38,12 @@ jobs:
|
||||
echo "COMFY_MODE=latest" >> "$GITHUB_ENV"
|
||||
echo "COMFY_REF=master" >> "$GITHUB_ENV"
|
||||
else
|
||||
PIN="$(sed -nE 's/^requires-comfyui *= *"==?([0-9a-f]+)".*/\1/p' pyproject.toml)"
|
||||
if [ -z "$PIN" ]; then echo "could not parse requires-comfyui from pyproject.toml"; exit 1; fi
|
||||
echo "COMFY_MODE=pinned" >> "$GITHUB_ENV"
|
||||
echo "COMFY_REF=$PIN" >> "$GITHUB_ENV"
|
||||
# requires-comfyui is a semver constraint (e.g. ">=0.3.27"); pin the
|
||||
# gate to the matching ComfyUI release tag (vX.Y.Z).
|
||||
VERSION="$(sed -nE 's/^requires-comfyui *= *"[^0-9]*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' pyproject.toml)"
|
||||
if [ -z "$VERSION" ]; then echo "could not parse requires-comfyui from pyproject.toml"; exit 1; fi
|
||||
echo "COMFY_MODE=pinned" >> "$GITHUB_ENV"
|
||||
echo "COMFY_REF=v$VERSION" >> "$GITHUB_ENV"
|
||||
fi
|
||||
|
||||
- name: Set up ComfyUI checkout
|
||||
@@ -113,10 +115,18 @@ jobs:
|
||||
done
|
||||
echo "comfy failed to start"; tail -100 /tmp/comfyui-ci.log; exit 1
|
||||
|
||||
- name: Purge cached Core ML UNets (force fresh conversion)
|
||||
# The converter skips when a model of the same name already exists. That
|
||||
# cache key is conversion *parameters* only, not the conversion code or
|
||||
# toolchain — so a stale model would let a conversion regression pass.
|
||||
# Clear it so every Tier 2 run exercises the full convert -> compile ->
|
||||
# sample path end to end.
|
||||
run: |
|
||||
rm -rf "$COMFY_DIR"/models/unet/*.mlpackage "$COMFY_DIR"/models/unet/*.mlmodelc || true
|
||||
|
||||
- name: Run Tier 2 (m2 marker)
|
||||
# The golden-image workflow drives the Core ML Converter node, so the
|
||||
# UNet is converted on demand on the first run and reused from the
|
||||
# runner-local cache afterwards.
|
||||
# Drives the Core ML Converter node, which converts the UNet from the
|
||||
# checkpoint on every run (cache purged above).
|
||||
run: uv run --no-sync pytest -m m2 tests/ -v
|
||||
|
||||
- name: Stop ComfyUI server
|
||||
|
||||
@@ -3,4 +3,3 @@ __pycache__/
|
||||
models/
|
||||
.venv/
|
||||
test_results/
|
||||
tests/m2/_latest_generated.png
|
||||
|
||||
@@ -8,8 +8,8 @@ These models are designed to leverage the Apple Neural Engine (ANE) on Apple Sil
|
||||
thereby enhancing your workflows and improving performance.
|
||||
|
||||
If you're not sure how to obtain these models, you can download them
|
||||
[here](https://huggingface.co/coreml-community) or convert your own models using
|
||||
[coremltools](https://github.com/apple/ml-stable-diffusion).
|
||||
[here](https://huggingface.co/coreml-community) or convert your own checkpoints
|
||||
directly with the conversion nodes in this suite (see [How to use](#how-to-use)).
|
||||
|
||||
In simple terms, think of Core ML models as a tool that can help your ComfyUI work faster and more efficiently.
|
||||
For instance, during my tests on an M2 Pro 32GB machine,
|
||||
@@ -81,6 +81,29 @@ These custom nodes come with a host of features, including:
|
||||
> [!NOTE]
|
||||
> This repository will continue to be updated with more nodes and features over time.
|
||||
|
||||
## Conversion & Acknowledgements
|
||||
|
||||
The Core ML conversion pipeline in this repository began as an adaptation of
|
||||
Apple's [ml-stable-diffusion](https://github.com/apple/ml-stable-diffusion),
|
||||
which pioneered running Stable Diffusion on the Apple Neural Engine. The
|
||||
implementation has since diverged and no longer depends on that package:
|
||||
|
||||
- UNet conversion runs natively on `diffusers`' `UNet2DConditionModel`.
|
||||
- The ANE-friendly attention path (`SPLIT_EINSUM`, `SPLIT_EINSUM_V2`) is
|
||||
reimplemented as standalone `diffusers` attention processors.
|
||||
- The toolchain tracks current ComfyUI (NumPy 2, Torch 2.7, coremltools 9,
|
||||
Python 3.12).
|
||||
|
||||
The goal is to keep iterating on these methods independently and to explore
|
||||
support beyond SD1.5.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Breaking change in 2.0.0.** The converted Core ML UNet now takes
|
||||
> `encoder_hidden_states` in the native `diffusers` layout
|
||||
> `(batch, tokens, hidden)` instead of the previous
|
||||
> `(batch, hidden, 1, tokens)`. Core ML models converted with earlier versions
|
||||
> are not compatible with 2.0.0 and must be re-converted.
|
||||
|
||||
## Installation
|
||||
|
||||
### Using ComfyUI-Manager
|
||||
@@ -408,16 +431,15 @@ PSNR is comfortably higher (the sampler averages over 20 steps).
|
||||
margin, `none` if you want bit-identical output for golden testing.
|
||||
|
||||
The default stays `none` so existing workflows produce byte-for-byte
|
||||
identical output — the golden-image anchor (`tests/m2/test_golden_image.py`)
|
||||
verifies this on every Tier 2 run.
|
||||
identical output.
|
||||
|
||||
## Limitations
|
||||
|
||||
- Core ML models are fixed in terms of their inputs and outputs.
|
||||
This means you'll need to use latent images of the same size as the input of the model (512x512 is the default for
|
||||
SD1.5).
|
||||
However, you can convert the model to a different input size using tools available
|
||||
in the [apple/ml-stable-diffusion](https://github.com/apple/ml-stable-diffusion) repository.
|
||||
However, you can re-convert the model to a different input size using the
|
||||
conversion nodes in this suite (set the desired width and height).
|
||||
- SD2.1 models are not supported.
|
||||
|
||||
[^1]:
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
ATTENTION_IMPLEMENTATIONS = (
|
||||
"SPLIT_EINSUM",
|
||||
"SPLIT_EINSUM_V2",
|
||||
"ORIGINAL",
|
||||
)
|
||||
@@ -1,17 +1,10 @@
|
||||
from enum import Enum
|
||||
|
||||
import torch
|
||||
|
||||
from comfy import supported_models_base
|
||||
from comfy import latent_formats
|
||||
from comfy.model_detection import convert_config
|
||||
|
||||
|
||||
class ModelVersion(Enum):
|
||||
SD15 = "sd15"
|
||||
SDXL = "sdxl"
|
||||
SDXL_REFINER = "sdxl_refiner"
|
||||
LCM = "lcm"
|
||||
from coreml_suite.model_version import ModelVersion
|
||||
|
||||
|
||||
config_map = {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
"""Core ML conversion helpers.
|
||||
|
||||
The conversion approach originates from Apple's ml-stable-diffusion
|
||||
(https://github.com/apple/ml-stable-diffusion). This implementation has since
|
||||
diverged: it runs natively on diffusers' UNet2DConditionModel with its own
|
||||
SPLIT_EINSUM / SPLIT_EINSUM_V2 attention processors and no longer depends on
|
||||
that package. The intent is to keep iterating on these methods independently
|
||||
while tracking current tooling.
|
||||
"""
|
||||
@@ -0,0 +1,239 @@
|
||||
import logging
|
||||
|
||||
import torch
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CHUNK_SIZE = 512
|
||||
|
||||
|
||||
def apply_attention_implementation(unet, attention_implementation):
|
||||
if attention_implementation == "ORIGINAL":
|
||||
return unet
|
||||
|
||||
if attention_implementation == "SPLIT_EINSUM":
|
||||
unet.set_attn_processor(SplitEinsumAttnProcessor())
|
||||
return unet
|
||||
|
||||
if attention_implementation == "SPLIT_EINSUM_V2":
|
||||
unet.set_attn_processor(SplitEinsumV2AttnProcessor())
|
||||
return unet
|
||||
|
||||
raise ValueError(f"Unsupported attention implementation: {attention_implementation}")
|
||||
|
||||
|
||||
class SplitEinsumAttnProcessor:
|
||||
def __call__(
|
||||
self,
|
||||
attn,
|
||||
hidden_states,
|
||||
encoder_hidden_states=None,
|
||||
attention_mask=None,
|
||||
temb=None,
|
||||
*args,
|
||||
**kwargs,
|
||||
):
|
||||
return _attention_forward(
|
||||
attn,
|
||||
hidden_states,
|
||||
encoder_hidden_states,
|
||||
attention_mask,
|
||||
temb,
|
||||
split_einsum,
|
||||
)
|
||||
|
||||
|
||||
class SplitEinsumV2AttnProcessor:
|
||||
def __call__(
|
||||
self,
|
||||
attn,
|
||||
hidden_states,
|
||||
encoder_hidden_states=None,
|
||||
attention_mask=None,
|
||||
temb=None,
|
||||
*args,
|
||||
**kwargs,
|
||||
):
|
||||
return _attention_forward(
|
||||
attn,
|
||||
hidden_states,
|
||||
encoder_hidden_states,
|
||||
attention_mask,
|
||||
temb,
|
||||
split_einsum_v2,
|
||||
)
|
||||
|
||||
|
||||
def _attention_forward(
|
||||
attn,
|
||||
hidden_states,
|
||||
encoder_hidden_states,
|
||||
attention_mask,
|
||||
temb,
|
||||
attention_fn,
|
||||
):
|
||||
residual = hidden_states
|
||||
|
||||
if attn.spatial_norm is not None:
|
||||
hidden_states = attn.spatial_norm(hidden_states, temb)
|
||||
|
||||
input_ndim = hidden_states.ndim
|
||||
if input_ndim == 4:
|
||||
batch_size, channel, height, width = hidden_states.shape
|
||||
hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
|
||||
else:
|
||||
batch_size, _, channel = hidden_states.shape
|
||||
height = None
|
||||
width = None
|
||||
|
||||
batch_size, key_sequence_length, _ = (
|
||||
hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
|
||||
)
|
||||
|
||||
if attention_mask is not None:
|
||||
attention_mask = attn.prepare_attention_mask(
|
||||
attention_mask,
|
||||
key_sequence_length,
|
||||
batch_size,
|
||||
)
|
||||
attention_mask = _prepare_split_einsum_mask(
|
||||
attention_mask,
|
||||
batch_size,
|
||||
attn.heads,
|
||||
key_sequence_length,
|
||||
)
|
||||
|
||||
if attn.group_norm is not None:
|
||||
hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
|
||||
|
||||
query = attn.to_q(hidden_states)
|
||||
|
||||
if encoder_hidden_states is None:
|
||||
encoder_hidden_states = hidden_states
|
||||
elif attn.norm_cross:
|
||||
encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
|
||||
|
||||
key = attn.to_k(encoder_hidden_states)
|
||||
value = attn.to_v(encoder_hidden_states)
|
||||
|
||||
batch_size = query.shape[0]
|
||||
dim_head = attn.inner_kv_dim // attn.heads
|
||||
|
||||
query = _linear_projection_to_bchw(query)
|
||||
key = _linear_projection_to_bchw(key)
|
||||
value = _linear_projection_to_bchw(value)
|
||||
|
||||
hidden_states = attention_fn(
|
||||
query,
|
||||
key,
|
||||
value,
|
||||
attention_mask,
|
||||
attn.heads,
|
||||
dim_head,
|
||||
)
|
||||
hidden_states = hidden_states.squeeze(2).transpose(1, 2)
|
||||
hidden_states = hidden_states.reshape(batch_size, -1, attn.inner_dim)
|
||||
|
||||
hidden_states = attn.to_out[0](hidden_states)
|
||||
hidden_states = attn.to_out[1](hidden_states)
|
||||
|
||||
if input_ndim == 4:
|
||||
hidden_states = hidden_states.transpose(-1, -2).reshape(
|
||||
batch_size,
|
||||
channel,
|
||||
height,
|
||||
width,
|
||||
)
|
||||
|
||||
if attn.residual_connection:
|
||||
hidden_states = hidden_states + residual
|
||||
|
||||
hidden_states = hidden_states / attn.rescale_output_factor
|
||||
return hidden_states
|
||||
|
||||
|
||||
def split_einsum(q, k, v, mask, heads, dim_head):
|
||||
q_heads = _split_heads(q, heads, dim_head)
|
||||
k = k.transpose(1, 3)
|
||||
k_heads = [
|
||||
k[:, :, :, head_idx * dim_head : (head_idx + 1) * dim_head]
|
||||
for head_idx in range(heads)
|
||||
]
|
||||
v_heads = _split_heads(v, heads, dim_head)
|
||||
|
||||
weights = [
|
||||
torch.einsum("bchq,bkhc->bkhq", query, key) * (dim_head**-0.5)
|
||||
for query, key in zip(q_heads, k_heads)
|
||||
]
|
||||
if mask is not None:
|
||||
weights = [weight + mask for weight in weights]
|
||||
|
||||
weights = [weight.softmax(dim=1) for weight in weights]
|
||||
outputs = [
|
||||
torch.einsum("bkhq,bchk->bchq", weight, value)
|
||||
for weight, value in zip(weights, v_heads)
|
||||
]
|
||||
return torch.cat(outputs, dim=1)
|
||||
|
||||
|
||||
def split_einsum_v2(q, k, v, mask, heads, dim_head):
|
||||
query_length = q.size(3)
|
||||
num_chunks = query_length // CHUNK_SIZE
|
||||
if num_chunks == 0:
|
||||
logger.info(
|
||||
"SPLIT_EINSUM_V2 query sequence is shorter than %s; using SPLIT_EINSUM.",
|
||||
CHUNK_SIZE,
|
||||
)
|
||||
return split_einsum(q, k, v, mask, heads, dim_head)
|
||||
|
||||
q_heads = _split_heads(q, heads, dim_head)
|
||||
q_chunks = [
|
||||
[
|
||||
head[..., chunk_idx * CHUNK_SIZE : (chunk_idx + 1) * CHUNK_SIZE]
|
||||
for chunk_idx in range(num_chunks)
|
||||
]
|
||||
for head in q_heads
|
||||
]
|
||||
|
||||
k = k.transpose(1, 3)
|
||||
k_heads = [
|
||||
k[:, :, :, head_idx * dim_head : (head_idx + 1) * dim_head]
|
||||
for head_idx in range(heads)
|
||||
]
|
||||
v_heads = _split_heads(v, heads, dim_head)
|
||||
|
||||
head_outputs = []
|
||||
for query_chunks, key, value in zip(q_chunks, k_heads, v_heads):
|
||||
chunk_outputs = []
|
||||
for query_chunk in query_chunks:
|
||||
weights = torch.einsum("bchq,bkhc->bkhq", query_chunk, key)
|
||||
weights = weights * (dim_head**-0.5)
|
||||
if mask is not None:
|
||||
weights = weights + mask
|
||||
weights = weights.softmax(dim=1)
|
||||
chunk_outputs.append(torch.einsum("bkhq,bchk->bchq", weights, value))
|
||||
head_outputs.append(torch.cat(chunk_outputs, dim=3))
|
||||
|
||||
return torch.cat(head_outputs, dim=1)
|
||||
|
||||
|
||||
def _split_heads(x, heads, dim_head):
|
||||
return [
|
||||
x[:, head_idx * dim_head : (head_idx + 1) * dim_head, :, :]
|
||||
for head_idx in range(heads)
|
||||
]
|
||||
|
||||
|
||||
def _linear_projection_to_bchw(x):
|
||||
return x.transpose(1, 2).unsqueeze(2)
|
||||
|
||||
|
||||
def _prepare_split_einsum_mask(mask, batch_size, heads, key_sequence_length):
|
||||
if mask.ndim == 2:
|
||||
mask = mask[:, None, :]
|
||||
if mask.shape[0] == batch_size * heads:
|
||||
mask = mask.reshape(batch_size, heads, -1, key_sequence_length)
|
||||
mask = mask[:, 0]
|
||||
if mask.ndim == 3:
|
||||
mask = mask[:, :, None, None]
|
||||
return mask
|
||||
@@ -0,0 +1,20 @@
|
||||
def conv2d_output_shape(height, width, conv):
|
||||
"""Return the spatial output shape for a torch.nn.Conv2d-like module."""
|
||||
kernel_h, kernel_w = _pair(conv.kernel_size)
|
||||
stride_h, stride_w = _pair(conv.stride)
|
||||
pad_h, pad_w = _pair(conv.padding)
|
||||
dilation_h, dilation_w = _pair(conv.dilation)
|
||||
|
||||
out_h = _conv_output_dim(height, kernel_h, stride_h, pad_h, dilation_h)
|
||||
out_w = _conv_output_dim(width, kernel_w, stride_w, pad_w, dilation_w)
|
||||
return out_h, out_w
|
||||
|
||||
|
||||
def _conv_output_dim(size, kernel, stride, padding, dilation):
|
||||
return ((size + (2 * padding) - (dilation * (kernel - 1)) - 1) // stride) + 1
|
||||
|
||||
|
||||
def _pair(value):
|
||||
if isinstance(value, tuple):
|
||||
return value
|
||||
return value, value
|
||||
@@ -0,0 +1,61 @@
|
||||
from types import MethodType
|
||||
|
||||
from diffusers.models.transformers.transformer_2d import Transformer2DModel
|
||||
|
||||
|
||||
def prepare_unet_for_coreml_trace(unet):
|
||||
for module in unet.modules():
|
||||
if isinstance(module, Transformer2DModel):
|
||||
module._operate_on_continuous_inputs = MethodType(
|
||||
_operate_on_continuous_inputs,
|
||||
module,
|
||||
)
|
||||
module._get_output_for_continuous_inputs = MethodType(
|
||||
_get_output_for_continuous_inputs,
|
||||
module,
|
||||
)
|
||||
return unet
|
||||
|
||||
|
||||
def _operate_on_continuous_inputs(self, hidden_states):
|
||||
hidden_states = self.norm(hidden_states)
|
||||
|
||||
if not self.use_linear_projection:
|
||||
hidden_states = self.proj_in(hidden_states)
|
||||
inner_dim = self.inner_dim
|
||||
hidden_states = hidden_states.flatten(2).transpose(1, 2)
|
||||
else:
|
||||
inner_dim = hidden_states.shape[1]
|
||||
hidden_states = hidden_states.flatten(2).transpose(1, 2)
|
||||
hidden_states = self.proj_in(hidden_states)
|
||||
|
||||
return hidden_states, inner_dim
|
||||
|
||||
|
||||
def _get_output_for_continuous_inputs(
|
||||
self,
|
||||
hidden_states,
|
||||
residual,
|
||||
batch_size,
|
||||
height,
|
||||
width,
|
||||
inner_dim,
|
||||
):
|
||||
if not self.use_linear_projection:
|
||||
hidden_states = hidden_states.transpose(1, 2).reshape(
|
||||
batch_size,
|
||||
inner_dim,
|
||||
height,
|
||||
width,
|
||||
)
|
||||
hidden_states = self.proj_out(hidden_states)
|
||||
else:
|
||||
hidden_states = self.proj_out(hidden_states)
|
||||
hidden_states = hidden_states.transpose(1, 2).reshape(
|
||||
batch_size,
|
||||
inner_dim,
|
||||
height,
|
||||
width,
|
||||
)
|
||||
|
||||
return hidden_states + residual
|
||||
@@ -0,0 +1,54 @@
|
||||
import torch
|
||||
|
||||
|
||||
class CoreMLUNetWrapper(torch.nn.Module):
|
||||
"""Adapt diffusers UNet inputs to CoreMLSuite's stable Core ML contract."""
|
||||
|
||||
def __init__(self, unet, model_version):
|
||||
super().__init__()
|
||||
self.unet = unet
|
||||
self.model_version = model_version
|
||||
|
||||
def forward(self, sample, timestep, encoder_hidden_states, *extra_inputs):
|
||||
input_index = 0
|
||||
timestep_cond = None
|
||||
if self._is_lcm:
|
||||
timestep_cond = extra_inputs[input_index]
|
||||
input_index += 1
|
||||
|
||||
added_cond_kwargs = None
|
||||
if self._is_sdxl:
|
||||
time_ids = extra_inputs[input_index]
|
||||
text_embeds = extra_inputs[input_index + 1]
|
||||
input_index += 2
|
||||
added_cond_kwargs = {
|
||||
"time_ids": time_ids,
|
||||
"text_embeds": text_embeds,
|
||||
}
|
||||
|
||||
additional_residuals = extra_inputs[input_index:]
|
||||
down_residuals = None
|
||||
mid_residual = None
|
||||
if additional_residuals:
|
||||
down_residuals = tuple(additional_residuals[:-1])
|
||||
mid_residual = additional_residuals[-1]
|
||||
|
||||
outputs = self.unet(
|
||||
sample,
|
||||
timestep,
|
||||
encoder_hidden_states=encoder_hidden_states,
|
||||
timestep_cond=timestep_cond,
|
||||
added_cond_kwargs=added_cond_kwargs,
|
||||
down_block_additional_residuals=down_residuals,
|
||||
mid_block_additional_residual=mid_residual,
|
||||
return_dict=False,
|
||||
)
|
||||
return outputs[0]
|
||||
|
||||
@property
|
||||
def _is_lcm(self):
|
||||
return self.model_version.name == "LCM"
|
||||
|
||||
@property
|
||||
def _is_sdxl(self):
|
||||
return self.model_version.name in {"SDXL", "SDXL_REFINER"}
|
||||
+61
-93
@@ -2,71 +2,38 @@ import gc
|
||||
import os
|
||||
import shutil
|
||||
import time
|
||||
from typing import Union
|
||||
|
||||
import coremltools as ct
|
||||
import numpy as np
|
||||
import python_coreml_stable_diffusion.unet
|
||||
import torch
|
||||
from diffusers import (
|
||||
StableDiffusionPipeline,
|
||||
LatentConsistencyModelPipeline,
|
||||
StableDiffusionXLPipeline,
|
||||
)
|
||||
from python_coreml_stable_diffusion.unet import (
|
||||
UNet2DConditionModel,
|
||||
UNet2DConditionModelXL,
|
||||
AttentionImplementations,
|
||||
)
|
||||
from diffusers import UNet2DConditionModel
|
||||
|
||||
from coreml_suite.config import ModelVersion
|
||||
from coreml_suite.lcm.unet import UNet2DConditionModelLCM
|
||||
from coreml_suite.attention import ATTENTION_IMPLEMENTATIONS
|
||||
from coreml_suite.conversion.attention import apply_attention_implementation
|
||||
from coreml_suite.conversion.shapes import conv2d_output_shape
|
||||
from coreml_suite.conversion.trace import prepare_unet_for_coreml_trace
|
||||
from coreml_suite.conversion.unet import CoreMLUNetWrapper
|
||||
from coreml_suite.logger import logger
|
||||
from folder_paths import get_folder_paths
|
||||
from coreml_suite.model_version import ModelVersion
|
||||
|
||||
DEFAULT_TRACE_TIMESTEP = 999.0
|
||||
TEXT_TOKEN_SEQUENCE_LENGTH = 77
|
||||
|
||||
|
||||
class StableDiffusionLCMPipeline(LatentConsistencyModelPipeline):
|
||||
pass
|
||||
|
||||
|
||||
MODEL_TYPE_TO_UNET_CLS = {
|
||||
ModelVersion.SD15: UNet2DConditionModel,
|
||||
ModelVersion.SDXL: UNet2DConditionModelXL,
|
||||
ModelVersion.LCM: UNet2DConditionModelLCM,
|
||||
}
|
||||
|
||||
MODEL_TYPE_TO_PIPE_CLS = {
|
||||
ModelVersion.SD15: StableDiffusionPipeline,
|
||||
ModelVersion.SDXL: StableDiffusionXLPipeline,
|
||||
ModelVersion.LCM: StableDiffusionLCMPipeline,
|
||||
}
|
||||
|
||||
|
||||
def get_unet(model_type: ModelVersion, ref_pipe):
|
||||
ref_unet = ref_pipe.unet
|
||||
|
||||
unet_cls = MODEL_TYPE_TO_UNET_CLS[model_type]
|
||||
cml_unet = unet_cls.from_config(ref_unet.config).eval()
|
||||
cml_unet.load_state_dict(ref_unet.state_dict(), strict=False)
|
||||
|
||||
return cml_unet
|
||||
|
||||
|
||||
def get_encoder_hidden_states_shape(ref_pipe, batch_size):
|
||||
text_encoder = (
|
||||
ref_pipe.text_encoder_2
|
||||
if hasattr(ref_pipe, "text_encoder_2")
|
||||
else ref_pipe.text_encoder
|
||||
def get_unet(model_version: ModelVersion, ref_unet, attention_implementation):
|
||||
ref_unet = prepare_unet_for_coreml_trace(ref_unet)
|
||||
unet = apply_attention_implementation(
|
||||
ref_unet.eval(),
|
||||
attention_implementation,
|
||||
)
|
||||
return CoreMLUNetWrapper(unet, model_version)
|
||||
|
||||
text_token_sequence_length = text_encoder.config.max_position_embeddings
|
||||
hidden_size = (text_encoder.config.hidden_size,)
|
||||
|
||||
def get_encoder_hidden_states_shape(ref_unet, batch_size):
|
||||
encoder_hidden_states_shape = (
|
||||
batch_size,
|
||||
ref_pipe.unet.config.cross_attention_dim or hidden_size,
|
||||
1,
|
||||
text_token_sequence_length,
|
||||
TEXT_TOKEN_SEQUENCE_LENGTH,
|
||||
ref_unet.config.cross_attention_dim,
|
||||
)
|
||||
|
||||
return encoder_hidden_states_shape
|
||||
@@ -122,6 +89,8 @@ def convert_to_coreml(
|
||||
|
||||
|
||||
def get_out_path(submodule_name, model_name):
|
||||
from folder_paths import get_folder_paths
|
||||
|
||||
fname = f"{model_name}_{submodule_name}.mlpackage"
|
||||
unet_path = get_folder_paths(submodule_name)[0]
|
||||
out_path = os.path.join(unet_path, fname)
|
||||
@@ -145,15 +114,13 @@ def compile_coreml_model(source_model_path, output_dir, final_name):
|
||||
return target_path
|
||||
|
||||
|
||||
def get_sample_input(batch_size, encoder_hidden_states_shape, sample_shape, scheduler):
|
||||
def get_sample_input(batch_size, encoder_hidden_states_shape, sample_shape):
|
||||
sample_unet_inputs = dict(
|
||||
[
|
||||
("sample", torch.rand(*sample_shape)),
|
||||
(
|
||||
"timestep",
|
||||
torch.tensor([scheduler.timesteps[0].item()] * batch_size).to(
|
||||
torch.float32
|
||||
),
|
||||
torch.tensor([DEFAULT_TRACE_TIMESTEP] * batch_size).to(torch.float32),
|
||||
),
|
||||
("encoder_hidden_states", torch.rand(*encoder_hidden_states_shape)),
|
||||
]
|
||||
@@ -166,7 +133,7 @@ def lcm_inputs(sample_unet_inputs):
|
||||
return {"timestep_cond": torch.randn(batch_size, 256).to(torch.float32)}
|
||||
|
||||
|
||||
def sdxl_inputs(sample_unet_inputs, ref_pipe):
|
||||
def sdxl_inputs(sample_unet_inputs, ref_unet, model_version):
|
||||
sample_shape = sample_unet_inputs["sample"].shape
|
||||
batch_size = sample_shape[0]
|
||||
h = sample_shape[2] * 8
|
||||
@@ -174,10 +141,7 @@ def sdxl_inputs(sample_unet_inputs, ref_pipe):
|
||||
original_size = (h, w)
|
||||
crops_coords_top_left = (0, 0)
|
||||
|
||||
is_refiner = (
|
||||
hasattr(ref_pipe.config, "requires_aesthetics_score")
|
||||
and ref_pipe.config.requires_aesthetics_score
|
||||
)
|
||||
is_refiner = model_version == ModelVersion.SDXL_REFINER
|
||||
|
||||
if is_refiner:
|
||||
aesthetic_score = (6.0,)
|
||||
@@ -187,7 +151,7 @@ def sdxl_inputs(sample_unet_inputs, ref_pipe):
|
||||
time_ids_list = list(original_size + crops_coords_top_left + target_size)
|
||||
|
||||
time_ids = torch.tensor(time_ids_list).repeat(batch_size, 1).to(torch.int64)
|
||||
text_embeds_shape = (batch_size, ref_pipe.text_encoder_2.config.hidden_size)
|
||||
text_embeds_shape = (batch_size, get_sdxl_text_embeds_dim(ref_unet, len(time_ids_list)))
|
||||
|
||||
return {
|
||||
"time_ids": time_ids,
|
||||
@@ -195,21 +159,25 @@ def sdxl_inputs(sample_unet_inputs, ref_pipe):
|
||||
}
|
||||
|
||||
|
||||
def get_sdxl_text_embeds_dim(ref_unet, time_ids_dim):
|
||||
projection_dim = ref_unet.config.projection_class_embeddings_input_dim
|
||||
time_embed_dim = ref_unet.config.addition_time_embed_dim
|
||||
return projection_dim - (time_ids_dim * time_embed_dim)
|
||||
|
||||
|
||||
def get_inputs_spec(inputs):
|
||||
inputs_spec = {k: (v.shape, v.dtype) for k, v in inputs.items()}
|
||||
return inputs_spec
|
||||
|
||||
|
||||
def add_cnet_support(sample_shape, reference_unet):
|
||||
from python_coreml_stable_diffusion.unet import calculate_conv2d_output_shape
|
||||
|
||||
additional_residuals_shapes = []
|
||||
|
||||
batch_size = sample_shape[0]
|
||||
h, w = sample_shape[2:]
|
||||
|
||||
# conv_in
|
||||
out_h, out_w = calculate_conv2d_output_shape(
|
||||
out_h, out_w = conv2d_output_shape(
|
||||
h,
|
||||
w,
|
||||
reference_unet.conv_in,
|
||||
@@ -226,9 +194,7 @@ def add_cnet_support(sample_shape, reference_unet):
|
||||
]
|
||||
if hasattr(down_block, "downsamplers") and down_block.downsamplers is not None:
|
||||
for downsampler in down_block.downsamplers:
|
||||
out_h, out_w = calculate_conv2d_output_shape(
|
||||
out_h, out_w, downsampler.conv
|
||||
)
|
||||
out_h, out_w = conv2d_output_shape(out_h, out_w, downsampler.conv)
|
||||
additional_residuals_shapes.append(
|
||||
(
|
||||
batch_size,
|
||||
@@ -252,16 +218,16 @@ def add_cnet_support(sample_shape, reference_unet):
|
||||
|
||||
|
||||
def convert_unet(
|
||||
ref_pipe,
|
||||
ref_unet,
|
||||
model_version: ModelVersion,
|
||||
unet_out_path: str,
|
||||
batch_size: int = 1,
|
||||
sample_size: tuple[int, int] = (64, 64),
|
||||
controlnet_support: bool = False,
|
||||
attention_implementation: str = ATTENTION_IMPLEMENTATIONS[0],
|
||||
quantize_nbits: str = "none",
|
||||
):
|
||||
coreml_unet = get_unet(model_version, ref_pipe)
|
||||
ref_unet = ref_pipe.unet
|
||||
coreml_unet = get_unet(model_version, ref_unet, attention_implementation)
|
||||
|
||||
sample_shape = (
|
||||
batch_size, # B
|
||||
@@ -270,20 +236,17 @@ def convert_unet(
|
||||
sample_size[1], # W
|
||||
)
|
||||
|
||||
encoder_hidden_states_shape = get_encoder_hidden_states_shape(ref_pipe, batch_size)
|
||||
|
||||
scheduler = ref_pipe.scheduler
|
||||
scheduler.set_timesteps(50)
|
||||
encoder_hidden_states_shape = get_encoder_hidden_states_shape(ref_unet, batch_size)
|
||||
|
||||
sample_inputs = get_sample_input(
|
||||
batch_size, encoder_hidden_states_shape, sample_shape, scheduler
|
||||
batch_size, encoder_hidden_states_shape, sample_shape
|
||||
)
|
||||
|
||||
if model_version == ModelVersion.LCM:
|
||||
sample_inputs |= lcm_inputs(sample_inputs)
|
||||
|
||||
if model_version == ModelVersion.SDXL:
|
||||
sample_inputs |= sdxl_inputs(sample_inputs, ref_pipe)
|
||||
if model_version in {ModelVersion.SDXL, ModelVersion.SDXL_REFINER}:
|
||||
sample_inputs |= sdxl_inputs(sample_inputs, ref_unet, model_version)
|
||||
|
||||
if controlnet_support:
|
||||
sample_inputs |= add_cnet_support(sample_shape, ref_unet)
|
||||
@@ -335,8 +298,8 @@ def convert(
|
||||
batch_size: int = 1,
|
||||
sample_size: tuple[int, int] = (64, 64),
|
||||
controlnet_support: bool = False,
|
||||
lora_weights: list[tuple[Union[str, os.PathLike], float]] = None,
|
||||
attn_impl: str = AttentionImplementations.SPLIT_EINSUM.name,
|
||||
lora_weights: list[tuple[str | os.PathLike, float]] = None,
|
||||
attn_impl: str = ATTENTION_IMPLEMENTATIONS[0],
|
||||
config_path: str = None,
|
||||
quantize_nbits: str = "none",
|
||||
):
|
||||
@@ -344,37 +307,42 @@ def convert(
|
||||
logger.info(f"Found existing model at {unet_out_path}! Skipping..")
|
||||
return
|
||||
|
||||
python_coreml_stable_diffusion.unet.ATTENTION_IMPLEMENTATION_IN_EFFECT = (
|
||||
AttentionImplementations(attn_impl)
|
||||
)
|
||||
|
||||
ref_pipe = get_pipeline(ckpt_path, config_path, model_version)
|
||||
if attn_impl not in ATTENTION_IMPLEMENTATIONS:
|
||||
raise ValueError(
|
||||
f"Unsupported attention implementation {attn_impl!r}. "
|
||||
f"Expected one of {ATTENTION_IMPLEMENTATIONS}."
|
||||
)
|
||||
ref_unet = load_unet(ckpt_path, config_path)
|
||||
|
||||
for i, lora_weight in enumerate(lora_weights or []):
|
||||
lora_path, strength = lora_weight
|
||||
adapter_name = f"lora_{i}"
|
||||
ref_pipe.load_lora_weights(lora_path, adapter_name=adapter_name)
|
||||
ref_pipe.set_adapters([adapter_name], adapter_weights=[strength])
|
||||
ref_pipe.fuse_lora()
|
||||
ref_unet.load_lora_adapter(lora_path, adapter_name=adapter_name)
|
||||
ref_unet.set_adapters([adapter_name], weights=[strength])
|
||||
ref_unet.fuse_lora()
|
||||
|
||||
convert_unet(
|
||||
ref_pipe,
|
||||
ref_unet,
|
||||
model_version,
|
||||
unet_out_path,
|
||||
batch_size,
|
||||
sample_size,
|
||||
controlnet_support,
|
||||
attention_implementation=attn_impl,
|
||||
quantize_nbits=quantize_nbits,
|
||||
)
|
||||
|
||||
|
||||
def get_pipeline(ckpt_path, config_path, model_version):
|
||||
pipe_cls = MODEL_TYPE_TO_PIPE_CLS[model_version]
|
||||
ref_pipe = pipe_cls.from_single_file(ckpt_path, original_config_file=config_path)
|
||||
return ref_pipe
|
||||
def load_unet(ckpt_path, config_path):
|
||||
return UNet2DConditionModel.from_single_file(
|
||||
ckpt_path,
|
||||
original_config=config_path,
|
||||
)
|
||||
|
||||
|
||||
def compile_model(out_path, out_name, submodule_name):
|
||||
from folder_paths import get_folder_paths
|
||||
|
||||
# Compile the model
|
||||
target_path = compile_coreml_model(
|
||||
out_path, get_folder_paths(submodule_name)[0], f"{out_name}_{submodule_name}"
|
||||
|
||||
@@ -24,7 +24,6 @@ class CoreMLInputs:
|
||||
sample = self.x.cpu().numpy().astype(np.float16)
|
||||
|
||||
context = self.context.cpu().numpy().astype(np.float16)
|
||||
context = context.transpose(0, 2, 1)[:, :, None, :]
|
||||
|
||||
t = self.t.cpu().numpy().astype(np.float16)
|
||||
|
||||
@@ -57,8 +56,7 @@ class CoreMLInputs:
|
||||
def chunks(self, expected_inputs):
|
||||
sample_shape = expected_inputs["sample"]["shape"]
|
||||
timestep_shape = expected_inputs["timestep"]["shape"]
|
||||
hidden_shape = expected_inputs["encoder_hidden_states"]["shape"]
|
||||
context_shape = (hidden_shape[0], hidden_shape[3], hidden_shape[1])
|
||||
context_shape = expected_inputs["encoder_hidden_states"]["shape"]
|
||||
|
||||
chunked_x = chunk_batch(self.x, sample_shape)
|
||||
ts = list(torch.full((len(chunked_x), timestep_shape[0]), self.t[0]))
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import time
|
||||
|
||||
import coremltools as ct
|
||||
|
||||
from coreml_suite.logger import logger
|
||||
|
||||
|
||||
class CoreMLModel:
|
||||
"""Small runtime wrapper around coremltools.models.MLModel.
|
||||
|
||||
This keeps the inference path independent from apple/ml-stable-diffusion's
|
||||
CoreMLModel wrapper while preserving the contract used by the sampler code:
|
||||
``expected_inputs`` and callable prediction.
|
||||
"""
|
||||
|
||||
def __init__(self, model_path, compute_unit):
|
||||
self.model_path = model_path
|
||||
self.compute_unit = self._compute_unit(compute_unit)
|
||||
|
||||
logger.info(f"Loading {model_path} to {self.compute_unit.name}")
|
||||
start = time.time()
|
||||
self.model = ct.models.MLModel(model_path, compute_units=self.compute_unit)
|
||||
logger.info(f"Loading {model_path} took {time.time() - start:.1f} seconds")
|
||||
|
||||
self.expected_inputs = self._expected_inputs()
|
||||
|
||||
def __call__(self, **kwargs):
|
||||
return self.model.predict(kwargs)
|
||||
|
||||
@staticmethod
|
||||
def _compute_unit(compute_unit):
|
||||
if isinstance(compute_unit, ct.ComputeUnit):
|
||||
return compute_unit
|
||||
return ct.ComputeUnit[compute_unit]
|
||||
|
||||
def _expected_inputs(self):
|
||||
return {
|
||||
feature.name: {
|
||||
"shape": tuple(feature.type.multiArrayType.shape),
|
||||
}
|
||||
for feature in self.model.get_spec().description.input
|
||||
}
|
||||
@@ -9,24 +9,20 @@ import torch
|
||||
from diffusers import UNet2DConditionModel, LCMScheduler
|
||||
from diffusers.loaders import LoraLoaderMixin
|
||||
|
||||
from comfy.model_management import get_torch_device
|
||||
from coreml_suite.lcm.unet import UNet2DConditionModelLCM
|
||||
from coreml_suite.conversion.attention import apply_attention_implementation
|
||||
from coreml_suite.conversion.shapes import conv2d_output_shape
|
||||
from coreml_suite.conversion.unet import CoreMLUNetWrapper
|
||||
from coreml_suite.model_version import ModelVersion
|
||||
|
||||
from transformers import CLIPTextModel
|
||||
import coremltools as ct
|
||||
|
||||
from folder_paths import get_folder_paths
|
||||
|
||||
logging.basicConfig()
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
MODEL_VERSION = "SimianLuo/LCM_Dreamshaper_v7"
|
||||
MODEL_NAME = MODEL_VERSION.split("/")[-1] + "_4k"
|
||||
|
||||
import python_coreml_stable_diffusion.unet as unet
|
||||
|
||||
unet.ATTENTION_IMPLEMENTATION_IN_EFFECT = unet.AttentionImplementations.SPLIT_EINSUM
|
||||
TEXT_TOKEN_SEQUENCE_LENGTH = 77
|
||||
|
||||
|
||||
def get_unets():
|
||||
@@ -37,31 +33,27 @@ def get_unets():
|
||||
low_cpu_mem_usage=False,
|
||||
)
|
||||
|
||||
cml_unet = UNet2DConditionModelLCM.from_config(ref_unet.config).eval()
|
||||
cml_unet.load_state_dict(ref_unet.state_dict(), strict=False)
|
||||
cml_unet = CoreMLUNetWrapper(
|
||||
apply_attention_implementation(ref_unet.eval(), "SPLIT_EINSUM"),
|
||||
ModelVersion.LCM,
|
||||
)
|
||||
|
||||
return cml_unet, ref_unet
|
||||
|
||||
|
||||
def get_encoder_hidden_states_shape(unet_config, batch_size):
|
||||
text_encoder = CLIPTextModel.from_pretrained(
|
||||
MODEL_VERSION, subfolder="text_encoder"
|
||||
)
|
||||
|
||||
text_token_sequence_length = text_encoder.config.max_position_embeddings
|
||||
hidden_size = (text_encoder.config.hidden_size,)
|
||||
|
||||
encoder_hidden_states_shape = (
|
||||
batch_size,
|
||||
unet_config.cross_attention_dim or hidden_size,
|
||||
1,
|
||||
text_token_sequence_length,
|
||||
TEXT_TOKEN_SEQUENCE_LENGTH,
|
||||
unet_config.cross_attention_dim,
|
||||
)
|
||||
|
||||
return encoder_hidden_states_shape
|
||||
|
||||
|
||||
def get_scheduler():
|
||||
from comfy.model_management import get_torch_device
|
||||
|
||||
scheduler = LCMScheduler.from_pretrained(MODEL_VERSION, subfolder="scheduler")
|
||||
scheduler.set_timesteps(50, get_torch_device(), 50)
|
||||
return scheduler
|
||||
@@ -117,6 +109,8 @@ def convert_to_coreml(
|
||||
|
||||
|
||||
def get_out_path(submodule_name, model_name):
|
||||
from folder_paths import get_folder_paths
|
||||
|
||||
fname = f"{model_name}_{submodule_name}.mlpackage"
|
||||
unet_path = get_folder_paths(submodule_name)[0]
|
||||
out_path = os.path.join(unet_path, fname)
|
||||
@@ -165,15 +159,13 @@ def get_unet_inputs_spec(sample_unet_inputs):
|
||||
|
||||
|
||||
def add_cnet_support(sample_shape, reference_unet):
|
||||
from python_coreml_stable_diffusion.unet import calculate_conv2d_output_shape
|
||||
|
||||
additional_residuals_shapes = []
|
||||
|
||||
batch_size = sample_shape[0]
|
||||
h, w = sample_shape[2:]
|
||||
|
||||
# conv_in
|
||||
out_h, out_w = calculate_conv2d_output_shape(
|
||||
out_h, out_w = conv2d_output_shape(
|
||||
h,
|
||||
w,
|
||||
reference_unet.conv_in,
|
||||
@@ -190,9 +182,7 @@ def add_cnet_support(sample_shape, reference_unet):
|
||||
]
|
||||
if hasattr(down_block, "downsamplers") and down_block.downsamplers is not None:
|
||||
for downsampler in down_block.downsamplers:
|
||||
out_h, out_w = calculate_conv2d_output_shape(
|
||||
out_h, out_w, downsampler.conv
|
||||
)
|
||||
out_h, out_w = conv2d_output_shape(out_h, out_w, downsampler.conv)
|
||||
additional_residuals_shapes.append(
|
||||
(
|
||||
batch_size,
|
||||
@@ -273,6 +263,8 @@ def convert(
|
||||
|
||||
|
||||
def compile_model(out_path, out_name):
|
||||
from folder_paths import get_folder_paths
|
||||
|
||||
# Compile the model
|
||||
target_path = compile_coreml_model(
|
||||
out_path, get_folder_paths("unet")[0], f"{out_name}_unet"
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import os
|
||||
|
||||
from coremltools import ComputeUnit
|
||||
from python_coreml_stable_diffusion.coreml_model import CoreMLModel
|
||||
|
||||
from coreml_suite import COREML_NODE
|
||||
from coreml_suite.lcm import converter as lcm_converter
|
||||
from coreml_suite.coreml_model import CoreMLModel
|
||||
|
||||
|
||||
class COREML_CONVERT_LCM(COREML_NODE):
|
||||
@@ -48,6 +47,8 @@ class COREML_CONVERT_LCM(COREML_NODE):
|
||||
The converted model is also saved to "models/unet" directory and
|
||||
can be loaded with the "LCMCoreMLLoaderUNet" node.
|
||||
"""
|
||||
from coreml_suite.lcm import converter as lcm_converter
|
||||
|
||||
h = height
|
||||
w = width
|
||||
sample_size = (h // 8, w // 8)
|
||||
@@ -67,4 +68,4 @@ class COREML_CONVERT_LCM(COREML_NODE):
|
||||
)
|
||||
target_path = lcm_converter.compile_model(out_path=out_path, out_name=out_name)
|
||||
|
||||
return (CoreMLModel(target_path, compute_unit, "compiled"),)
|
||||
return (CoreMLModel(target_path, compute_unit),)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from overrides import overrides
|
||||
from python_coreml_stable_diffusion.unet import UNet2DConditionModel, TimestepEmbedding
|
||||
from diffusers import UNet2DConditionModel
|
||||
from diffusers.models.embeddings import TimestepEmbedding
|
||||
|
||||
|
||||
class UNet2DConditionModelLCM(UNet2DConditionModel):
|
||||
@@ -17,7 +17,6 @@ class UNet2DConditionModelLCM(UNet2DConditionModel):
|
||||
)
|
||||
self.time_embedding = time_embedding
|
||||
|
||||
@overrides(check_signature=False)
|
||||
def forward(
|
||||
self,
|
||||
sample,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class ModelVersion(Enum):
|
||||
SD15 = "sd15"
|
||||
SDXL = "sdxl"
|
||||
SDXL_REFINER = "sdxl_refiner"
|
||||
LCM = "lcm"
|
||||
+8
-13
@@ -1,13 +1,11 @@
|
||||
import os
|
||||
|
||||
from coremltools import ComputeUnit
|
||||
from python_coreml_stable_diffusion.coreml_model import CoreMLModel
|
||||
from python_coreml_stable_diffusion.unet import AttentionImplementations
|
||||
|
||||
import folder_paths
|
||||
from coreml_suite import COREML_NODE
|
||||
from coreml_suite import converter
|
||||
from coreml_suite.config import ModelVersion
|
||||
from coreml_suite.attention import ATTENTION_IMPLEMENTATIONS
|
||||
from coreml_suite.coreml_model import CoreMLModel
|
||||
from coreml_suite.core.naming import (
|
||||
QUANT_NBITS_VALUES,
|
||||
compose_out_name,
|
||||
@@ -15,6 +13,7 @@ from coreml_suite.core.naming import (
|
||||
)
|
||||
from coreml_suite.lcm.utils import add_lcm_model_options, lcm_patch, is_lcm
|
||||
from coreml_suite.logger import logger
|
||||
from coreml_suite.model_version import ModelVersion
|
||||
from nodes import KSampler, LoraLoader, KSamplerAdvanced
|
||||
|
||||
from coreml_suite.models import (
|
||||
@@ -179,9 +178,7 @@ class CoreMLLoader(COREML_NODE):
|
||||
|
||||
coreml_path = self.coreml_filenames()[coreml_name]
|
||||
|
||||
sources = "compiled" if coreml_name.endswith(".mlmodelc") else "packages"
|
||||
|
||||
return (CoreMLModel(coreml_path, compute_unit, sources),)
|
||||
return (CoreMLModel(coreml_path, compute_unit),)
|
||||
|
||||
|
||||
class CoreMLLoaderUNet(CoreMLLoader):
|
||||
@@ -232,11 +229,7 @@ class CoreMLConverter(COREML_NODE):
|
||||
"width": ("INT", {"default": 512, "min": 256, "max": 2048, "step": 8}),
|
||||
"batch_size": ("INT", {"default": 1, "min": 1, "max": 64}),
|
||||
"attention_implementation": (
|
||||
[
|
||||
AttentionImplementations.SPLIT_EINSUM.name,
|
||||
AttentionImplementations.SPLIT_EINSUM_V2.name,
|
||||
AttentionImplementations.ORIGINAL.name,
|
||||
],
|
||||
list(ATTENTION_IMPLEMENTATIONS),
|
||||
),
|
||||
"compute_unit": (
|
||||
[
|
||||
@@ -322,6 +315,8 @@ class CoreMLConverter(COREML_NODE):
|
||||
for lora_param in lora_params:
|
||||
logger.info(f" {lora_param[0]} - strength: {lora_param[1]}")
|
||||
|
||||
from coreml_suite import converter
|
||||
|
||||
unet_out_path = converter.get_out_path("unet", f"{out_name}")
|
||||
ckpt_path = folder_paths.get_full_path("checkpoints", ckpt_name)
|
||||
|
||||
@@ -346,7 +341,7 @@ class CoreMLConverter(COREML_NODE):
|
||||
out_path=unet_out_path, out_name=out_name, submodule_name="unet"
|
||||
)
|
||||
|
||||
return (CoreMLModel(unet_target_path, compute_unit, "compiled"),)
|
||||
return (CoreMLModel(unet_target_path, compute_unit),)
|
||||
|
||||
@staticmethod
|
||||
def lora_path(lora_name):
|
||||
|
||||
+8
-46
@@ -1,50 +1,35 @@
|
||||
[project]
|
||||
name = "comfyui-coremlsuite"
|
||||
description = "This extension contains a set of custom nodes for ComfyUI that allow you to use Core ML models in your ComfyUI workflows."
|
||||
version = "1.0.1"
|
||||
version = "2.0.0"
|
||||
license = "MIT"
|
||||
requires-python = ">=3.12,<3.13"
|
||||
packages = [{ include = "coreml_suite" }]
|
||||
dependencies = [
|
||||
# Python 3.12, coremltools 9, torch 2.7.
|
||||
# numpy stays in the 1.24..1.x range — none of our modules need
|
||||
# numpy 2, and coremltools + ml-stable-diffusion's SD UNet trace
|
||||
# hit hard bugs under numpy 2 (`_cast` int(ndarray) strictness and
|
||||
# `view` mixed-Var shape lists).
|
||||
# torch 2.7 is the latest version coremltools 9's PyTorch frontend
|
||||
# has been tested against.
|
||||
"python-coreml-stable-diffusion @ git+https://github.com/apple/ml-stable-diffusion.git@e5d960c41a6a4ab200b8db379194127607b1c590",
|
||||
"torch>=2.7,<2.8",
|
||||
"coremltools>=9,<10",
|
||||
"numpy>=1.24,<2",
|
||||
"overrides",
|
||||
"diffusers>=0.22",
|
||||
"peft>=0.6.2",
|
||||
"numpy>=2,<3",
|
||||
"diffusers>=0.30",
|
||||
"peft>=0.13",
|
||||
"omegaconf>=2.3",
|
||||
"transformers>=4.44",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Repository = "https://github.com/aszc-dev/ComfyUI-CoreMLSuite"
|
||||
# Used by Comfy Registry https://comfyregistry.org
|
||||
|
||||
[tool.comfy]
|
||||
PublisherId = "aszc-dev"
|
||||
DisplayName = "ComfyUI-CoreMLSuite"
|
||||
Icon = ""
|
||||
# Pinned to the ComfyUI commit this toolchain was validated against.
|
||||
requires-comfyui = "==ab5413351eee61f3d7f10c74e75286df0058bb18"
|
||||
requires-comfyui = ">=0.3.27"
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"pillow>=12.2.0",
|
||||
"psutil>=7.2.2",
|
||||
"pytest>=9.0.3",
|
||||
]
|
||||
# ComfyUI runtime deps that aren't part of our package's runtime contract
|
||||
# but are needed to spin up the ComfyUI server for Tier 2 integration tests.
|
||||
# Kept in a uv group so `uv sync --group comfy` brings them in without
|
||||
# polluting the published metadata (and without re-bumping our torch pin
|
||||
# via `uv pip install -r ComfyUI/requirements.txt`, which would float to
|
||||
# the latest torch and break the coremltools 9 compatibility ceiling).
|
||||
comfy = [
|
||||
"comfyui-frontend-package==1.14.6",
|
||||
"torchvision",
|
||||
@@ -61,34 +46,11 @@ comfy = [
|
||||
"sentencepiece",
|
||||
]
|
||||
|
||||
[tool.uv]
|
||||
# ml-stable-diffusion's setup.py hard-pins numpy<1.24, diffusers==0.30.2
|
||||
# and transformers==4.44.2, which blocks the modern torch / coremltools
|
||||
# combo on Python 3.12. Override the four blocking pins; the .unet /
|
||||
# .coreml_model symbols we actually import are stable across the bumped
|
||||
# versions.
|
||||
override-dependencies = [
|
||||
"numpy>=1.24,<2",
|
||||
"diffusers>=0.30",
|
||||
"transformers>=4.44",
|
||||
"huggingface-hub>=0.24",
|
||||
]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
# Tier markers gate which environment a test needs.
|
||||
# - unit: framework-free pure-logic tests (Tier 0; run without ComfyUI on
|
||||
# Linux).
|
||||
# - m2: needs an Apple Silicon Mac with the Neural Engine (Tier 2),
|
||||
# typically a self-hosted runner or local M-series box.
|
||||
# - smoke: lightweight checks that need Apple Silicon + coremltools but no
|
||||
# ANE/real model (Tier 1).
|
||||
markers = [
|
||||
"unit: framework-free unit test (Tier 0)",
|
||||
"m2: requires Apple Silicon + Neural Engine (Tier 2)",
|
||||
"smoke: macOS-ARM smoke test on a synthetic micro-model (Tier 1)",
|
||||
"m2: requires Apple Silicon + Neural Engine (Tier 2)",
|
||||
]
|
||||
testpaths = ["tests"]
|
||||
# importlib mode keeps pytest from importing the repo-root __init__.py
|
||||
# (which is the ComfyUI custom-node entry and pulls in comfy + nodes).
|
||||
# Without this Tier-0 leaks the entire ComfyUI runtime on collection.
|
||||
addopts = ["--import-mode=importlib", "--confcutdir=tests"]
|
||||
|
||||
+4
-5
@@ -1,8 +1,7 @@
|
||||
git+https://github.com/apple/ml-stable-diffusion.git@e5d960c41a6a4ab200b8db379194127607b1c590
|
||||
torch>=2.7,<2.8
|
||||
coremltools==8.2
|
||||
coremltools>=9,<10
|
||||
numpy>=2,<3
|
||||
overrides
|
||||
diffusers>=0.22
|
||||
peft>=0.6.2
|
||||
diffusers>=0.30
|
||||
peft>=0.13
|
||||
omegaconf>=2.3
|
||||
transformers>=4.44
|
||||
|
||||
+4
-4
@@ -4,7 +4,7 @@
|
||||
that transitively import `comfy.*` resolve when pytest is invoked from
|
||||
this package's root.
|
||||
- Auto-applies tier markers based on the directory a test lives in, so
|
||||
individual files don't have to repeat @pytest.mark.unit / .m2.
|
||||
individual files don't have to repeat @pytest.mark.unit / .smoke.
|
||||
"""
|
||||
import sys
|
||||
from pathlib import Path
|
||||
@@ -26,9 +26,9 @@ _TIER_BY_DIR = {
|
||||
"tests/smoke": "smoke",
|
||||
}
|
||||
|
||||
# When the user asks for a single tier (-m unit / -m m2), skip the other
|
||||
# directories at collection time. Tier-0 cannot afford to import tests/m2
|
||||
# files because they pull in PIL + ComfyUI runtime which Linux CI won't have.
|
||||
# When the user asks for a single tier (-m unit / -m smoke), skip the other
|
||||
# directories at collection time. Tier-0 cannot afford to import tests/smoke
|
||||
# files because they pull in coremltools which Linux CI won't have.
|
||||
_TIER_DIRS = {
|
||||
"unit": ("/tests/unit/",),
|
||||
"m2": ("/tests/m2/", "/tests/integration/"),
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import platform
|
||||
|
||||
import pytest
|
||||
import torch
|
||||
from diffusers.models.attention_processor import Attention, AttnProcessor
|
||||
|
||||
from coreml_suite.conversion.attention import (
|
||||
SplitEinsumAttnProcessor,
|
||||
SplitEinsumV2AttnProcessor,
|
||||
)
|
||||
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
platform.system() != "Darwin" or platform.machine() != "arm64",
|
||||
reason="Tier 1 requires macOS on Apple Silicon",
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"processor",
|
||||
[
|
||||
SplitEinsumAttnProcessor(),
|
||||
SplitEinsumV2AttnProcessor(),
|
||||
],
|
||||
)
|
||||
def test_split_einsum_processor_matches_diffusers_attention(processor):
|
||||
torch.manual_seed(0)
|
||||
reference = Attention(query_dim=32, heads=4, dim_head=8, dropout=0.0)
|
||||
reference.set_processor(AttnProcessor())
|
||||
|
||||
candidate = Attention(query_dim=32, heads=4, dim_head=8, dropout=0.0)
|
||||
candidate.load_state_dict(reference.state_dict())
|
||||
candidate.set_processor(processor)
|
||||
|
||||
hidden_states = torch.randn(2, 17, 32)
|
||||
encoder_hidden_states = torch.randn(2, 11, 32)
|
||||
|
||||
expected = reference(hidden_states, encoder_hidden_states=encoder_hidden_states)
|
||||
actual = candidate(hidden_states, encoder_hidden_states=encoder_hidden_states)
|
||||
|
||||
assert torch.allclose(actual, expected, atol=1e-5)
|
||||
@@ -1,13 +1,13 @@
|
||||
"""Tier 1 smoke: convert a synthetic micro-UNet through coremltools and load
|
||||
it back with python_coreml_stable_diffusion's CoreMLModel.
|
||||
it back with CoreMLSuite's runtime CoreMLModel wrapper.
|
||||
|
||||
Purpose: catch API breakage in coremltools / ml-stable-diffusion *without*
|
||||
needing a real SD checkpoint, the ANE, or a converted .mlmodelc on disk.
|
||||
Purpose: catch API breakage in coremltools *without* needing a real SD
|
||||
checkpoint, the ANE, or a converted .mlmodelc on disk.
|
||||
Runs in minutes on a hosted macOS-ARM runner (no Apple internal stuff).
|
||||
|
||||
What it asserts:
|
||||
- coremltools.convert still accepts the call shape we use today
|
||||
- the resulting .mlpackage round-trips through CoreMLModel
|
||||
- the resulting .mlpackage round-trips through CoreMLSuite's CoreMLModel
|
||||
- expected_inputs exposes the input names/shapes we declared
|
||||
- calling the model returns the named output (`noise_pred`)
|
||||
|
||||
@@ -15,12 +15,15 @@ Auto-skips on non-Apple-Silicon hosts so Tier 0 CI on Linux ignores it.
|
||||
"""
|
||||
import platform
|
||||
import shutil
|
||||
from types import SimpleNamespace
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
|
||||
from coreml_suite.conversion.unet import CoreMLUNetWrapper
|
||||
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
platform.system() != "Darwin" or platform.machine() != "arm64",
|
||||
@@ -32,7 +35,7 @@ pytestmark = pytest.mark.skipif(
|
||||
# coremltools, small enough that conversion finishes in seconds on CPU.
|
||||
SAMPLE_SHAPE = (1, 4, 8, 8)
|
||||
TIMESTEP_SHAPE = (1,)
|
||||
ENCODER_SHAPE = (1, 64, 1, 4) # matches SD's transposed encoder_hidden_states layout
|
||||
ENCODER_SHAPE = (1, 4, 64) # native diffusers encoder_hidden_states (batch, tokens, hidden)
|
||||
OUT_NAME = "noise_pred"
|
||||
|
||||
|
||||
@@ -41,7 +44,7 @@ class TinyUNet(nn.Module):
|
||||
|
||||
Not a real diffusion model. Just enough op variety to exercise the
|
||||
PyTorch -> MIL frontend in coremltools and confirm we can still wire
|
||||
the inputs/outputs the way ml-stable-diffusion expects.
|
||||
the inputs/outputs the way CoreMLSuite's runtime expects.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
@@ -51,12 +54,22 @@ class TinyUNet(nn.Module):
|
||||
self.time_proj = nn.Linear(1, 8)
|
||||
self.text_proj = nn.Linear(64, 8)
|
||||
|
||||
def forward(self, sample, timestep, encoder_hidden_states):
|
||||
def forward(
|
||||
self,
|
||||
sample,
|
||||
timestep,
|
||||
encoder_hidden_states,
|
||||
timestep_cond=None,
|
||||
added_cond_kwargs=None,
|
||||
down_block_additional_residuals=None,
|
||||
mid_block_additional_residual=None,
|
||||
return_dict=True,
|
||||
):
|
||||
h = self.conv_in(sample)
|
||||
t_emb = self.time_proj(timestep.unsqueeze(-1)).view(1, 8, 1, 1)
|
||||
c_emb = self.text_proj(encoder_hidden_states.squeeze(2).mean(-1)).view(1, 8, 1, 1)
|
||||
c_emb = self.text_proj(encoder_hidden_states.mean(1)).view(1, 8, 1, 1)
|
||||
h = h + t_emb + c_emb
|
||||
return self.conv_out(h)
|
||||
return (self.conv_out(h),)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@@ -65,7 +78,10 @@ def tiny_mlpackage(tmp_path_factory):
|
||||
import coremltools as ct
|
||||
|
||||
torch.manual_seed(0)
|
||||
model = TinyUNet().eval()
|
||||
model = CoreMLUNetWrapper(
|
||||
TinyUNet().eval(),
|
||||
SimpleNamespace(name="SD15"),
|
||||
)
|
||||
example = (
|
||||
torch.randn(*SAMPLE_SHAPE),
|
||||
torch.randn(*TIMESTEP_SHAPE),
|
||||
@@ -95,9 +111,9 @@ def tiny_mlpackage(tmp_path_factory):
|
||||
|
||||
|
||||
def test_coremltools_convert_round_trips_via_coreml_model(tiny_mlpackage):
|
||||
from python_coreml_stable_diffusion.coreml_model import CoreMLModel
|
||||
from coreml_suite.coreml_model import CoreMLModel
|
||||
|
||||
model = CoreMLModel(str(tiny_mlpackage), "CPU_ONLY", "packages")
|
||||
model = CoreMLModel(str(tiny_mlpackage), "CPU_ONLY")
|
||||
|
||||
# expected_inputs is the contract our wrappers depend on. Lock the shape
|
||||
# of the dict + a sample entry.
|
||||
|
||||
@@ -30,7 +30,7 @@ SD15_RESIDUAL_SPEC = {
|
||||
}
|
||||
NON_RESIDUAL_SPEC = {
|
||||
"sample": {"shape": (2, 4, 64, 64)},
|
||||
"encoder_hidden_states": {"shape": (2, 768, 1, 77)},
|
||||
"encoder_hidden_states": {"shape": (2, 77, 768)},
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ def _deterministic_seed():
|
||||
SD15_EXPECTED = {
|
||||
"sample": {"shape": (2, 4, 64, 64)},
|
||||
"timestep": {"shape": (2,)},
|
||||
"encoder_hidden_states": {"shape": (2, 768, 1, 77)},
|
||||
"encoder_hidden_states": {"shape": (2, 77, 768)},
|
||||
}
|
||||
|
||||
SD15_WITH_CN = {
|
||||
@@ -42,7 +42,7 @@ LCM_EXPECTED = {
|
||||
SDXL_BASE_EXPECTED = {
|
||||
"sample": {"shape": (2, 4, 128, 128)},
|
||||
"timestep": {"shape": (2,)},
|
||||
"encoder_hidden_states": {"shape": (2, 2048, 1, 77)},
|
||||
"encoder_hidden_states": {"shape": (2, 77, 2048)},
|
||||
"time_ids": {"shape": (2, 6)},
|
||||
"text_embeds": {"shape": (2, 1280)},
|
||||
}
|
||||
@@ -50,7 +50,7 @@ SDXL_BASE_EXPECTED = {
|
||||
SDXL_REFINER_EXPECTED = {
|
||||
"sample": {"shape": (2, 4, 128, 128)},
|
||||
"timestep": {"shape": (2,)},
|
||||
"encoder_hidden_states": {"shape": (2, 1280, 1, 77)},
|
||||
"encoder_hidden_states": {"shape": (2, 77, 1280)},
|
||||
"time_ids": {"shape": (2, 5)},
|
||||
"text_embeds": {"shape": (2, 1280)},
|
||||
}
|
||||
@@ -93,8 +93,8 @@ def test_coreml_kwargs_sd15_shapes_and_fp16():
|
||||
assert set(out.keys()) == {"sample", "encoder_hidden_states", "timestep"}
|
||||
assert out["sample"].shape == (1, 4, 64, 64)
|
||||
assert out["sample"].dtype == np.float16
|
||||
# encoder_hidden_states is transposed (b, seq, dim) -> (b, dim, 1, seq).
|
||||
assert out["encoder_hidden_states"].shape == (1, 768, 1, 77)
|
||||
# encoder_hidden_states keeps Comfy's native (b, seq, dim) layout.
|
||||
assert out["encoder_hidden_states"].shape == (1, 77, 768)
|
||||
assert out["encoder_hidden_states"].dtype == np.float16
|
||||
assert out["timestep"].shape == (1,)
|
||||
assert out["timestep"].dtype == np.float16
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
The SDXL time_ids / text_embeds math lives in
|
||||
coreml_suite.core.sdxl as pure builders. The framework adapter
|
||||
add_sdxl_model_options (in models.py) is exercised separately by the m2
|
||||
golden image test; here we just lock the pure math.
|
||||
add_sdxl_model_options lives in models.py; here we just lock the pure
|
||||
math.
|
||||
"""
|
||||
import inspect
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ def expected_inputs():
|
||||
"sample": {"shape": (2, 4, 64, 64)},
|
||||
"timestep": {"shape": (2,)},
|
||||
"timestep_cond": {"shape": (2, 256)},
|
||||
"encoder_hidden_states": {"shape": (2, 768, 1, 77)},
|
||||
"encoder_hidden_states": {"shape": (2, 77, 768)},
|
||||
"additional_residual_0": {"shape": (2, 320, 64, 64)},
|
||||
"additional_residual_1": {"shape": (2, 640, 32, 32)},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
from types import SimpleNamespace
|
||||
|
||||
import torch
|
||||
|
||||
from coreml_suite.conversion.attention import (
|
||||
SplitEinsumAttnProcessor,
|
||||
SplitEinsumV2AttnProcessor,
|
||||
apply_attention_implementation,
|
||||
split_einsum,
|
||||
split_einsum_v2,
|
||||
)
|
||||
from coreml_suite.conversion.shapes import conv2d_output_shape
|
||||
from coreml_suite.conversion.unet import CoreMLUNetWrapper
|
||||
|
||||
|
||||
class RecordingUNet(torch.nn.Module):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.call = None
|
||||
|
||||
def forward(
|
||||
self,
|
||||
sample,
|
||||
timestep,
|
||||
encoder_hidden_states,
|
||||
timestep_cond=None,
|
||||
added_cond_kwargs=None,
|
||||
down_block_additional_residuals=None,
|
||||
mid_block_additional_residual=None,
|
||||
return_dict=True,
|
||||
**kwargs,
|
||||
):
|
||||
self.call = {
|
||||
"sample": sample,
|
||||
"timestep": timestep,
|
||||
"encoder_hidden_states": encoder_hidden_states,
|
||||
"timestep_cond": timestep_cond,
|
||||
"added_cond_kwargs": added_cond_kwargs,
|
||||
"down_block_additional_residuals": down_block_additional_residuals,
|
||||
"mid_block_additional_residual": mid_block_additional_residual,
|
||||
"return_dict": return_dict,
|
||||
}
|
||||
return (sample + 1,)
|
||||
|
||||
|
||||
def test_conv2d_output_shape_matches_torch_conv2d_contract():
|
||||
conv = torch.nn.Conv2d(
|
||||
4,
|
||||
8,
|
||||
kernel_size=(3, 5),
|
||||
stride=(2, 3),
|
||||
padding=(1, 2),
|
||||
dilation=(1, 2),
|
||||
)
|
||||
|
||||
assert conv2d_output_shape(17, 19, conv) == (9, 5)
|
||||
|
||||
|
||||
def test_unet_wrapper_passes_context_through_for_sd15():
|
||||
unet = RecordingUNet()
|
||||
wrapper = CoreMLUNetWrapper(unet, SimpleNamespace(name="SD15"))
|
||||
|
||||
sample = torch.randn(2, 4, 8, 8)
|
||||
timestep = torch.randn(2)
|
||||
context = torch.randn(2, 77, 768)
|
||||
|
||||
out = wrapper(sample, timestep, context)
|
||||
|
||||
assert torch.equal(out, sample + 1)
|
||||
assert unet.call["encoder_hidden_states"] is context
|
||||
assert unet.call["return_dict"] is False
|
||||
|
||||
|
||||
def test_unet_wrapper_routes_lcm_sdxl_and_controlnet_inputs():
|
||||
unet = RecordingUNet()
|
||||
wrapper = CoreMLUNetWrapper(unet, SimpleNamespace(name="LCM"))
|
||||
|
||||
sample = torch.randn(1, 4, 8, 8)
|
||||
timestep = torch.randn(1)
|
||||
context = torch.randn(1, 77, 768)
|
||||
timestep_cond = torch.randn(1, 256)
|
||||
down_residual = torch.randn(1, 320, 8, 8)
|
||||
mid_residual = torch.randn(1, 1280, 1, 1)
|
||||
|
||||
wrapper(sample, timestep, context, timestep_cond, down_residual, mid_residual)
|
||||
|
||||
assert unet.call["timestep_cond"] is timestep_cond
|
||||
assert len(unet.call["down_block_additional_residuals"]) == 1
|
||||
assert unet.call["down_block_additional_residuals"][0] is down_residual
|
||||
assert unet.call["mid_block_additional_residual"] is mid_residual
|
||||
|
||||
|
||||
def test_unet_wrapper_routes_sdxl_added_conditioning():
|
||||
unet = RecordingUNet()
|
||||
wrapper = CoreMLUNetWrapper(unet, SimpleNamespace(name="SDXL"))
|
||||
|
||||
sample = torch.randn(1, 4, 8, 8)
|
||||
timestep = torch.randn(1)
|
||||
context = torch.randn(1, 77, 2048)
|
||||
time_ids = torch.randn(1, 6)
|
||||
text_embeds = torch.randn(1, 1280)
|
||||
|
||||
wrapper(sample, timestep, context, time_ids, text_embeds)
|
||||
|
||||
assert unet.call["added_cond_kwargs"]["time_ids"] is time_ids
|
||||
assert unet.call["added_cond_kwargs"]["text_embeds"] is text_embeds
|
||||
|
||||
|
||||
def test_split_einsum_matches_original_attention_math():
|
||||
torch.manual_seed(0)
|
||||
batch = 2
|
||||
heads = 3
|
||||
dim_head = 4
|
||||
sequence = 16
|
||||
channels = heads * dim_head
|
||||
q = torch.randn(batch, channels, 1, sequence)
|
||||
k = torch.randn(batch, channels, 1, sequence)
|
||||
v = torch.randn(batch, channels, 1, sequence)
|
||||
|
||||
expected = _original_attention(q, k, v, None, heads, dim_head)
|
||||
|
||||
# split-einsum reorders the float32 reductions vs the reference, so equality
|
||||
# only holds up to rounding; the drift exceeds allclose's default atol on
|
||||
# some BLAS backends (e.g. Linux x86 CI).
|
||||
assert torch.allclose(split_einsum(q, k, v, None, heads, dim_head), expected, atol=1e-6)
|
||||
assert torch.allclose(split_einsum_v2(q, k, v, None, heads, dim_head), expected, atol=1e-6)
|
||||
|
||||
|
||||
def test_split_einsum_v2_chunked_path_matches_original_attention_math():
|
||||
torch.manual_seed(0)
|
||||
batch = 1
|
||||
heads = 2
|
||||
dim_head = 2
|
||||
sequence = 512
|
||||
channels = heads * dim_head
|
||||
q = torch.randn(batch, channels, 1, sequence)
|
||||
k = torch.randn(batch, channels, 1, sequence)
|
||||
v = torch.randn(batch, channels, 1, sequence)
|
||||
|
||||
expected = _original_attention(q, k, v, None, heads, dim_head)
|
||||
|
||||
assert torch.allclose(
|
||||
split_einsum_v2(q, k, v, None, heads, dim_head),
|
||||
expected,
|
||||
atol=1e-6,
|
||||
)
|
||||
|
||||
|
||||
def test_apply_attention_implementation_sets_split_processors():
|
||||
unet = RecordingProcessorUNet()
|
||||
|
||||
assert apply_attention_implementation(unet, "ORIGINAL") is unet
|
||||
assert unet.processor is None
|
||||
|
||||
apply_attention_implementation(unet, "SPLIT_EINSUM")
|
||||
assert isinstance(unet.processor, SplitEinsumAttnProcessor)
|
||||
|
||||
apply_attention_implementation(unet, "SPLIT_EINSUM_V2")
|
||||
assert isinstance(unet.processor, SplitEinsumV2AttnProcessor)
|
||||
|
||||
|
||||
class RecordingProcessorUNet:
|
||||
def __init__(self):
|
||||
self.processor = None
|
||||
|
||||
def set_attn_processor(self, processor):
|
||||
self.processor = processor
|
||||
|
||||
|
||||
def _original_attention(q, k, v, mask, heads, dim_head):
|
||||
batch = q.size(0)
|
||||
mh_q = q.view(batch, heads, dim_head, -1)
|
||||
mh_k = k.view(batch, heads, dim_head, -1)
|
||||
mh_v = v.view(batch, heads, dim_head, -1)
|
||||
|
||||
weights = torch.einsum("bhcq,bhck->bhqk", mh_q, mh_k)
|
||||
weights = weights * (dim_head**-0.5)
|
||||
if mask is not None:
|
||||
weights = weights + mask
|
||||
weights = weights.softmax(dim=3)
|
||||
|
||||
attn = torch.einsum("bhqk,bhck->bhcq", weights, mh_v)
|
||||
return attn.contiguous().view(batch, heads * dim_head, 1, -1)
|
||||
@@ -7,10 +7,10 @@ after collection. If they are, a tests/unit/ file is transitively
|
||||
pulling them in and the Tier-0 promise — "runs on Linux with no Mac
|
||||
stack" — is broken.
|
||||
|
||||
When other tiers (m2 / integration) are also collected, comfy is
|
||||
expected in sys.modules (integration imports it deliberately), so the
|
||||
check is skipped in mixed runs — Tier-0 purity is only meaningful when
|
||||
nothing else is loaded.
|
||||
When other tiers are also collected, framework modules may be imported
|
||||
deliberately (e.g. smoke pulls in coremltools), so the check is skipped
|
||||
unless the run is purely `-m unit` — Tier-0 purity is only meaningful
|
||||
when nothing else is loaded.
|
||||
"""
|
||||
import sys
|
||||
|
||||
|
||||
@@ -2,14 +2,6 @@ version = 1
|
||||
revision = 3
|
||||
requires-python = "==3.12.*"
|
||||
|
||||
[manifest]
|
||||
overrides = [
|
||||
{ name = "diffusers", specifier = ">=0.30" },
|
||||
{ name = "huggingface-hub", specifier = ">=0.24" },
|
||||
{ name = "numpy", specifier = ">=1.24,<2" },
|
||||
{ name = "transformers", specifier = ">=4.44" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "accelerate"
|
||||
version = "1.13.0"
|
||||
@@ -85,12 +77,12 @@ wheels = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "annotated-types"
|
||||
version = "0.7.0"
|
||||
name = "annotated-doc"
|
||||
version = "0.0.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -100,20 +92,17 @@ source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/3e/38/7859ff46355f76f8d19459005ca000b6e7012f2f1ca597746cbcd1fbfe5e/antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b", size = 117034, upload-time = "2021-11-06T17:52:23.524Z" }
|
||||
|
||||
[[package]]
|
||||
name = "argmaxtools"
|
||||
version = "0.1.23"
|
||||
name = "anyio"
|
||||
version = "4.13.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "beartype" },
|
||||
{ name = "coremltools" },
|
||||
{ name = "huggingface-hub" },
|
||||
{ name = "jaxtyping" },
|
||||
{ name = "scikit-learn" },
|
||||
{ name = "tabulate" },
|
||||
{ name = "torch" },
|
||||
{ name = "wandb" },
|
||||
{ name = "idna" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622, upload-time = "2026-03-24T12:59:09.671Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/21/23/b7a21bd4c6c124b2e42d6c25bdd66c1ad0656d0ed9e86caf9387e8353cae/argmaxtools-0.1.23.tar.gz", hash = "sha256:2f275f490bb18d56f8340f0e0bfcb527ac208a5fbdaa20e1a2003960e8ec2499", size = 43365, upload-time = "2025-07-08T00:43:22.404Z" }
|
||||
|
||||
[[package]]
|
||||
name = "attrs"
|
||||
@@ -124,15 +113,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "beartype"
|
||||
version = "0.22.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c7/94/1009e248bbfbab11397abca7193bea6626806be9a327d399810d523a07cb/beartype-0.22.9.tar.gz", hash = "sha256:8f82b54aa723a2848a56008d18875f91c1db02c32ef6a62319a002e3e25a975f", size = 1608866, upload-time = "2025-12-13T06:50:30.72Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/71/cc/18245721fa7747065ab478316c7fea7c74777d07f37ae60db2e84f8172e8/beartype-0.22.9-py3-none-any.whl", hash = "sha256:d16c9bbc61ea14637596c5f6fbff2ee99cbe3573e46a716401734ef50c3060c2", size = 1333658, upload-time = "2025-12-13T06:50:28.266Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cattrs"
|
||||
version = "26.1.0"
|
||||
@@ -226,17 +206,16 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "comfyui-coremlsuite"
|
||||
version = "1.0.1"
|
||||
version = "2.0.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "coremltools" },
|
||||
{ name = "diffusers" },
|
||||
{ name = "numpy" },
|
||||
{ name = "omegaconf" },
|
||||
{ name = "overrides" },
|
||||
{ name = "peft" },
|
||||
{ name = "python-coreml-stable-diffusion" },
|
||||
{ name = "torch" },
|
||||
{ name = "transformers" },
|
||||
]
|
||||
|
||||
[package.dev-dependencies]
|
||||
@@ -258,18 +237,18 @@ comfy = [
|
||||
dev = [
|
||||
{ name = "pillow" },
|
||||
{ name = "psutil" },
|
||||
{ name = "pytest" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "coremltools", specifier = ">=9,<10" },
|
||||
{ name = "diffusers", specifier = ">=0.22" },
|
||||
{ name = "numpy", specifier = ">=1.24,<2" },
|
||||
{ name = "diffusers", specifier = ">=0.30" },
|
||||
{ name = "numpy", specifier = ">=2,<3" },
|
||||
{ name = "omegaconf", specifier = ">=2.3" },
|
||||
{ name = "overrides" },
|
||||
{ name = "peft", specifier = ">=0.6.2" },
|
||||
{ name = "python-coreml-stable-diffusion", git = "https://github.com/apple/ml-stable-diffusion.git?rev=e5d960c41a6a4ab200b8db379194127607b1c590" },
|
||||
{ name = "peft", specifier = ">=0.13" },
|
||||
{ name = "torch", specifier = ">=2.7,<2.8" },
|
||||
{ name = "transformers", specifier = ">=4.44" },
|
||||
]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
@@ -291,6 +270,7 @@ comfy = [
|
||||
dev = [
|
||||
{ name = "pillow", specifier = ">=12.2.0" },
|
||||
{ name = "psutil", specifier = ">=7.2.2" },
|
||||
{ name = "pytest", specifier = ">=9.0.3" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -302,27 +282,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/00/25/26c0d75006470d32bfc9eb39ac61a22600bfa509d672405ff3fe1561e2a8/comfyui_frontend_package-1.14.6-py3-none-any.whl", hash = "sha256:1044e30ff3c025dfb63f4c68ecd808a77050c3a5cc3c1f3e6421ea39800bbf40", size = 34873501, upload-time = "2025-03-27T15:50:30.726Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "contourpy"
|
||||
version = "1.3.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "numpy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54", size = 13466130, upload-time = "2025-04-15T17:47:53.79Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/34/f7/44785876384eff370c251d58fd65f6ad7f39adce4a093c934d4a67a7c6b6/contourpy-1.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4caf2bcd2969402bf77edc4cb6034c7dd7c0803213b3523f111eb7460a51b8d2", size = 271580, upload-time = "2025-04-15T17:37:03.105Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/3b/0004767622a9826ea3d95f0e9d98cd8729015768075d61f9fea8eeca42a8/contourpy-1.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82199cb78276249796419fe36b7386bd8d2cc3f28b3bc19fe2454fe2e26c4c15", size = 255530, upload-time = "2025-04-15T17:37:07.026Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/bb/7bd49e1f4fa805772d9fd130e0d375554ebc771ed7172f48dfcd4ca61549/contourpy-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106fab697af11456fcba3e352ad50effe493a90f893fca6c2ca5c033820cea92", size = 307688, upload-time = "2025-04-15T17:37:11.481Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/97/e1d5dbbfa170725ef78357a9a0edc996b09ae4af170927ba8ce977e60a5f/contourpy-1.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d14f12932a8d620e307f715857107b1d1845cc44fdb5da2bc8e850f5ceba9f87", size = 347331, upload-time = "2025-04-15T17:37:18.212Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/66/e69e6e904f5ecf6901be3dd16e7e54d41b6ec6ae3405a535286d4418ffb4/contourpy-1.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:532fd26e715560721bb0d5fc7610fce279b3699b018600ab999d1be895b09415", size = 318963, upload-time = "2025-04-15T17:37:22.76Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/32/b8a1c8965e4f72482ff2d1ac2cd670ce0b542f203c8e1d34e7c3e6925da7/contourpy-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b383144cf2d2c29f01a1e8170f50dacf0eac02d64139dcd709a8ac4eb3cfe", size = 323681, upload-time = "2025-04-15T17:37:33.001Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/c6/12a7e6811d08757c7162a541ca4c5c6a34c0f4e98ef2b338791093518e40/contourpy-1.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c49f73e61f1f774650a55d221803b101d966ca0c5a2d6d5e4320ec3997489441", size = 1308674, upload-time = "2025-04-15T17:37:48.64Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/8a/bebe5a3f68b484d3a2b8ffaf84704b3e343ef1addea528132ef148e22b3b/contourpy-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3d80b2c0300583228ac98d0a927a1ba6a2ba6b8a742463c564f1d419ee5b211e", size = 1380480, upload-time = "2025-04-15T17:38:06.7Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/db/fcd325f19b5978fb509a7d55e06d99f5f856294c1991097534360b307cf1/contourpy-1.3.2-cp312-cp312-win32.whl", hash = "sha256:90df94c89a91b7362e1142cbee7568f86514412ab8a2c0d0fca72d7e91b62912", size = 178489, upload-time = "2025-04-15T17:38:10.338Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/c8/fadd0b92ffa7b5eb5949bf340a63a4a496a6930a6c37a7ba0f12acb076d6/contourpy-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c942a01d9163e2e5cfb05cb66110121b8d07ad438a17f9e766317bcb62abf73", size = 223042, upload-time = "2025-04-15T17:38:14.239Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "coremltools"
|
||||
version = "9.0"
|
||||
@@ -344,21 +303,13 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/87/add15e7b4537765bef9cb47ffbd6a5d48493e65181df9864afeffa13b99b/coremltools-9.0-cp312-none-manylinux1_x86_64.whl", hash = "sha256:99a101085a7919de9f1c18e514c17d2b3e6a06ad4f7a35aae9515ad47f5a843f", size = 2308591, upload-time = "2025-11-10T21:48:47.269Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cycler"
|
||||
version = "0.12.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diffusers"
|
||||
version = "0.30.2"
|
||||
version = "0.37.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "filelock" },
|
||||
{ name = "httpx" },
|
||||
{ name = "huggingface-hub" },
|
||||
{ name = "importlib-metadata" },
|
||||
{ name = "numpy" },
|
||||
@@ -367,28 +318,9 @@ dependencies = [
|
||||
{ name = "requests" },
|
||||
{ name = "safetensors" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/04/ee/13a6327f04f21420ab4d8ada635aba7d884bf57b09f9b847b9af3818b348/diffusers-0.30.2.tar.gz", hash = "sha256:641875f78f36bdfa4b9af752b124d1fd6d431eadd5547fe0a3f354ae0af2636c", size = 2095560, upload-time = "2024-08-31T00:05:36.947Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/46/5c/f4c2eb8d481fe8784a7e2331fbaab820079c06676185fa6d2177b386d590/diffusers-0.37.1.tar.gz", hash = "sha256:2346c21f77f835f273b7aacbaada1c34a596a3a2cc6ddc99d149efcd0ec298fa", size = 4135139, upload-time = "2026-03-25T08:04:04.515Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/ee/f67b0888229be96a276257579a58eb2331733d246fdb8620e09ca7253971/diffusers-0.30.2-py3-none-any.whl", hash = "sha256:739826043147c2b59560944591dfdea5d24cd4fb15e751abbe20679a289bece8", size = 2636928, upload-time = "2024-08-31T00:05:34.542Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diffusionkit"
|
||||
version = "0.4.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "argmaxtools" },
|
||||
{ name = "jaxtyping" },
|
||||
{ name = "mlx" },
|
||||
{ name = "pillow" },
|
||||
{ name = "safetensors" },
|
||||
{ name = "sentencepiece" },
|
||||
{ name = "torch" },
|
||||
{ name = "transformers" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5c/7c/107e46c576ea639646a4370f6ad806d88dad9edeb2d0bb1c4abba55b8858/diffusionkit-0.4.0.tar.gz", hash = "sha256:d13721321e91258e5b6355366d0b2d7042ee4f8a9163c6e3eac492e250c19706", size = 45115, upload-time = "2024-09-09T23:52:38.971Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/1f/d972cd232a2346b03a2bf380d99ade51271ea97bf491efa414799a3b682f/diffusionkit-0.4.0-py3-none-any.whl", hash = "sha256:1e977165a6f638a7c587f95253b13f3f804ab7838a40b03a3876ed45cf64162d", size = 52994, upload-time = "2024-09-09T23:52:37.875Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/dd/51c38785ce5e1c287b5ad17ba550edaaaffce0deb0da4857019c6700fbaf/diffusers-0.37.1-py3-none-any.whl", hash = "sha256:0537c0b28cb53cf39d6195489bcf8f833986df556c10f5e28ab7427b86fc8b90", size = 5001536, upload-time = "2026-03-25T08:04:02.385Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -409,23 +341,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl", hash = "sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258", size = 39812, upload-time = "2026-04-19T15:39:08.752Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fonttools"
|
||||
version = "4.63.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/84/69/c97f2c18e0db87d2c7b15da1974dace76ae938f1cfa22e2727a648b7ed43/fonttools-4.63.0.tar.gz", hash = "sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0", size = 3597189, upload-time = "2026-05-14T12:04:30.958Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/08/ef/b3c6b9b5be2f82416d73fe2ed2e96e2793cd80e7510bd6a17ca79cdd88ec/fonttools-4.63.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:37dd23e621e3b0aef1baa70a303b80aaf38449632cfc8fd2a55fb285bbccfc02", size = 2881131, upload-time = "2026-05-14T12:03:13.386Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/a0/c815bea63117fa63e4e1c01f8a1110d2112fa003f838e6467094ec2432ce/fonttools-4.63.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a9faff9e0c1f76f9fd55899d2ce785832efebab37eb8ae13995853aef178bef0", size = 2426704, upload-time = "2026-05-14T12:03:15.801Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/04/0b91d8e916e92ad1fac9e4624760baf0fd5ff2ead614c2f68fb21373f03f/fonttools-4.63.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef3048ef05dbb552b89817713d9cac912e00d0fde4a3105c00d29e52e10c89af", size = 5044298, upload-time = "2026-05-14T12:03:18.085Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/c7/2342da9830e3e9d4870305ca5d2091d2a83284f2953079b7bdd3b5e029d8/fonttools-4.63.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58dc6bb86a78d782f00f9190ca02c119cf5bbe2807536e361e18d42019f877d8", size = 4999800, upload-time = "2026-05-14T12:03:20.161Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/6d/67fe16c48d7ce050979b33f47e0d28a318f02da030602e944c34f7a16ef3/fonttools-4.63.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee08ebfa58f6e1aeff5697ab9582105bb620008c1caafb681e4c557e7483027b", size = 4982666, upload-time = "2026-05-14T12:03:22.87Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/00/3bbab338c07c71fa56269953845e92c951a61457bbbb0f1022551ea266d9/fonttools-4.63.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:27fdc65af8da6f88b9c6121c47a464cbe359fcfff7ff6fc2d37a1f395d755b78", size = 5133598, upload-time = "2026-05-14T12:03:25.168Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/f2/aa27c7f98db5b064883dadcc5283947e81e034de42e22a33675878d98b54/fonttools-4.63.0-cp312-cp312-win32.whl", hash = "sha256:af2fd1664d00a397d75f806985ddb36282091c2131a73a6485c23b4a34722263", size = 2292575, upload-time = "2026-05-14T12:03:27.496Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/36/cccb9bc2a6ab63d1b2980374f0dca72ce95ae267c9b4cfe77455bb70d0d4/fonttools-4.63.0-cp312-cp312-win_amd64.whl", hash = "sha256:59ac449f8cca9b4ffa08d2e7bbadad87ce710d69d1eda5c3c1ce579baa987272", size = 2343211, upload-time = "2026-05-14T12:03:30.057Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "frozenlist"
|
||||
version = "1.8.0"
|
||||
@@ -461,45 +376,76 @@ wheels = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gitdb"
|
||||
version = "4.0.12"
|
||||
name = "h11"
|
||||
version = "0.16.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "smmap" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gitpython"
|
||||
version = "3.1.50"
|
||||
name = "hf-xet"
|
||||
version = "1.5.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/74/d8/5c06fc76461418326a7decf8367480c35be11a41fd938633929c60a9ec6b/hf_xet-1.5.0.tar.gz", hash = "sha256:e0fb0a34d9f406eed88233e829a67ec016bec5af19e480eac65a233ea289a948", size = 837196, upload-time = "2026-05-06T06:18:15.583Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/fb/69ff198a82cae7eb1a69fb84d93b3a3e4816564d76817fe541ddc96874eb/hf_xet-1.5.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:dad0dc84e941b8ba3c860659fe1fdc35c049d47cce293f003287757e971a8f56", size = 4030814, upload-time = "2026-05-06T06:17:57.933Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/ff/edcc2b40162bef3ff78e14ab637e5f3b89243d6aee72f5949d3bb6a5af83/hf_xet-1.5.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:fd6e5a9b0fdac4ed03ed45ef79254a655b1aaab514a02202617fbf643f5fdf7a", size = 3798444, upload-time = "2026-05-06T06:17:55.79Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/4d/103f76b04310e5e57656696cc184690d20c466af0bca3ca88f8c8ea5d4f3/hf_xet-1.5.0-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3531b1823a0e6d77d80f9ed15ca0e00f0d115094f8ac033d5cae88f4564cc949", size = 4465986, upload-time = "2026-05-06T06:17:44.886Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/a2/546f47f464737b3edbab6f8ddb57f2599b93d2cbb66f06abb475ccb48651/hf_xet-1.5.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:9a0ee58cd18d5ea799f7ed11290bbccbe56bdd8b1d97ca74b9cc49a3945d7a3b", size = 4259865, upload-time = "2026-05-06T06:17:42.639Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/7f/1be593c1f28613be2e196473481cd81bfc5910795e30a34e8f744f6cac4f/hf_xet-1.5.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1e60df5a42e9bed8628b6416af2cba4cba57ae9f02de226a06b020d98e1aab18", size = 4459835, upload-time = "2026-05-06T06:18:08.026Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/b2/703569fc881f3284487e68cda7b42179978480da3c438042a6bbbb4a671c/hf_xet-1.5.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4b35549ce62601b84da4ff9b24d970032ace3d4430f52d91bcbb26c901d6c690", size = 4672414, upload-time = "2026-05-06T06:18:09.864Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/37/1b6def445c567286b50aa3b33828158e135b1be44938dde59f11382a500c/hf_xet-1.5.0-cp37-abi3-win_amd64.whl", hash = "sha256:2806c7c17b4d23f8d88f7c4814f838c3b6150773fe339c20af23e1cfaf2797e4", size = 3977238, upload-time = "2026-05-06T06:18:23.621Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/94/3b66b148778ee100dcfd69c2ca22b57b41b44d3063ceec934f209e9184ce/hf_xet-1.5.0-cp37-abi3-win_arm64.whl", hash = "sha256:b6c9df403040248c76d808d3e047d64db2d923bae593eb244c41e425cf6cd7be", size = 3806916, upload-time = "2026-05-06T06:18:21.7Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
version = "1.0.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "gitdb" },
|
||||
{ name = "certifi" },
|
||||
{ name = "h11" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/33/f6/354ae6491228b5eb40e10d89c4d13c651fe1cf7556e35ebdded50cff57ce/gitpython-3.1.50.tar.gz", hash = "sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc", size = 219798, upload-time = "2026-05-06T04:01:26.571Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl", hash = "sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9", size = 212507, upload-time = "2026-05-06T04:01:23.799Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
version = "0.28.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "certifi" },
|
||||
{ name = "httpcore" },
|
||||
{ name = "idna" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "huggingface-hub"
|
||||
version = "0.24.6"
|
||||
version = "1.16.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "filelock" },
|
||||
{ name = "fsspec" },
|
||||
{ name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" },
|
||||
{ name = "httpx" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "requests" },
|
||||
{ name = "tqdm" },
|
||||
{ name = "typer" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/65/24/b98fce967b7d63700e5805b915012ba25bb538a81fcf11e97f3cc3f4f012/huggingface_hub-0.24.6.tar.gz", hash = "sha256:cc2579e761d070713eaa9c323e3debe39d5b464ae3a7261c39a9195b27bb8000", size = 349200, upload-time = "2024-08-19T15:15:03.822Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/48/0f/ed994dbade67a54407c28cab96ef845e0e6d25500be56aca6394f8bfc9dd/huggingface_hub-1.16.1.tar.gz", hash = "sha256:7f1dc4c5ec21aed69be630ad0c3378616be16f3de1a47b141c0e812965d9c832", size = 792534, upload-time = "2026-05-21T18:40:00.908Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/8f/d6718641c14d98a5848c6a24d2376028d292074ffade0702940a4b1dde76/huggingface_hub-0.24.6-py3-none-any.whl", hash = "sha256:a990f3232aa985fe749bc9474060cbad75e8b2f115f6665a9fda5b9c97818970", size = 417509, upload-time = "2024-08-19T15:15:01.429Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/79/621a7dbb80c70974f73a597275351ebe03ce5bc65cb5f8f4acb5859252bc/huggingface_hub-1.16.1-py3-none-any.whl", hash = "sha256:64340de934b9ce37857ef85a82de72f5629e8a270f9119eabb12bf495eb53c22", size = 668176, upload-time = "2026-05-21T18:39:58.596Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -532,33 +478,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "invisible-watermark"
|
||||
version = "0.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "numpy" },
|
||||
{ name = "opencv-python" },
|
||||
{ name = "pillow" },
|
||||
{ name = "pywavelets" },
|
||||
{ name = "torch" },
|
||||
]
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/57/18b5a914f6d7994dd349252873169e946dc824328e9a37fd15ed836deedc/invisible_watermark-0.2.0-py3-none-any.whl", hash = "sha256:644311beed9cfe4a9a5a4a46c740f47800cef184fe2e1297f3f4542e2d992f8b", size = 1633253, upload-time = "2023-07-06T13:56:28.715Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jaxtyping"
|
||||
version = "0.3.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "wadler-lindig" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c2/be/00294e369938937e31b094437d5ea040e4fd1a20b998ebe572c4a1dcfa68/jaxtyping-0.3.9.tar.gz", hash = "sha256:f8c02d1b623d5f1b6665d4f3ddaec675d70004f16a792102c2fc51264190951d", size = 45857, upload-time = "2026-02-16T10:35:13.263Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/94/05/3e39d416fb92b2738a76e8265e6bfc5d10542f90a7c32ad1eb831eea3fa3/jaxtyping-0.3.9-py3-none-any.whl", hash = "sha256:a00557a9d616eff157491f06ed2e21ed94886fad3832399273eb912b345da378", size = 56274, upload-time = "2026-02-16T10:35:11.795Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.1.6"
|
||||
@@ -571,42 +490,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "joblib"
|
||||
version = "1.5.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/41/f2/d34e8b3a08a9cc79a50b2208a93dce981fe615b64d5a4d4abee421d898df/joblib-1.5.3.tar.gz", hash = "sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3", size = 331603, upload-time = "2025-12-15T08:41:46.427Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kiwisolver"
|
||||
version = "1.5.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a", size = 103482, upload-time = "2026-03-09T13:15:53.382Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/b2/818b74ebea34dabe6d0c51cb1c572e046730e64844da6ed646d5298c40ce/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9", size = 123158, upload-time = "2026-03-09T13:13:23.127Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/d9/405320f8077e8e1c5c4bd6adc45e1e6edf6d727b6da7f2e2533cf58bff71/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588", size = 66388, upload-time = "2026-03-09T13:13:24.765Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/9f/795fedf35634f746151ca8839d05681ceb6287fbed6cc1c9bf235f7887c2/kiwisolver-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819", size = 64068, upload-time = "2026-03-09T13:13:25.878Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/13/680c54afe3e65767bed7ec1a15571e1a2f1257128733851ade24abcefbcc/kiwisolver-1.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f", size = 1477934, upload-time = "2026-03-09T13:13:27.166Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/2f/cebfcdb60fd6a9b0f6b47a9337198bcbad6fbe15e68189b7011fd914911f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf", size = 1278537, upload-time = "2026-03-09T13:13:28.707Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/0d/9b782923aada3fafb1d6b84e13121954515c669b18af0c26e7d21f579855/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d", size = 1296685, upload-time = "2026-03-09T13:13:30.528Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/70/83241b6634b04fe44e892688d5208332bde130f38e610c0418f9ede47ded/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083", size = 1346024, upload-time = "2026-03-09T13:13:32.818Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/db/30ed226fb271ae1a6431fc0fe0edffb2efe23cadb01e798caeb9f2ceae8f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6", size = 987241, upload-time = "2026-03-09T13:13:34.435Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/bd/c314595208e4c9587652d50959ead9e461995389664e490f4dce7ff0f782/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1", size = 2227742, upload-time = "2026-03-09T13:13:36.4Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/43/0499cec932d935229b5543d073c2b87c9c22846aab48881e9d8d6e742a2d/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0", size = 2323966, upload-time = "2026-03-09T13:13:38.204Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/6f/79b0d760907965acfd9d61826a3d41f8f093c538f55cd2633d3f0db269f6/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15", size = 1977417, upload-time = "2026-03-09T13:13:39.966Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/31/01d0537c41cb75a551a438c3c7a80d0c60d60b81f694dac83dd436aec0d0/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314", size = 2491238, upload-time = "2026-03-09T13:13:41.698Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/34/8aefdd0be9cfd00a44509251ba864f5caf2991e36772e61c408007e7f417/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9", size = 2294947, upload-time = "2026-03-09T13:13:43.343Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/cf/0348374369ca588f8fe9c338fae49fa4e16eeb10ffb3d012f23a54578a9e/kiwisolver-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384", size = 73569, upload-time = "2026-03-09T13:13:45.792Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/26/192b26196e2316e2bd29deef67e37cdf9870d9af8e085e521afff0fed526/kiwisolver-1.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7", size = 64997, upload-time = "2026-03-09T13:13:46.878Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/fa/2910df836372d8761bb6eff7d8bdcb1613b5c2e03f260efe7abe34d388a7/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_10_13_x86_64.whl", hash = "sha256:5ae8e62c147495b01a0f4765c878e9bfdf843412446a247e28df59936e99e797", size = 130262, upload-time = "2026-03-09T13:15:35.629Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/41/c5f71f9f00aabcc71fee8b7475e3f64747282580c2fe748961ba29b18385/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203", size = 138036, upload-time = "2026-03-09T13:15:36.894Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/06/7399a607f434119c6e1fdc8ec89a8d51ccccadf3341dee4ead6bd14caaf5/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7", size = 194295, upload-time = "2026-03-09T13:15:38.22Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/91/53255615acd2a1eaca307ede3c90eb550bae9c94581f8c00081b6b1c8f44/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57", size = 75987, upload-time = "2026-03-09T13:15:39.65Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kornia"
|
||||
version = "0.8.3"
|
||||
@@ -634,6 +517,18 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/6f/01e0e2cf90c47ecf26656263cdabe491a1b206c94c0c30a1dd7e4d13ed29/kornia_rs-0.1.14-cp312-cp312-win_amd64.whl", hash = "sha256:ac4bbd0a8fd73b5058a39707c790fecec4c5204a42d1f5af17f1fa57cc83d406", size = 3367565, upload-time = "2026-05-19T07:46:16.682Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markdown-it-py"
|
||||
version = "4.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mdurl" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markupsafe"
|
||||
version = "3.0.3"
|
||||
@@ -654,54 +549,12 @@ wheels = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matplotlib"
|
||||
version = "3.10.9"
|
||||
name = "mdurl"
|
||||
version = "0.1.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "contourpy" },
|
||||
{ name = "cycler" },
|
||||
{ name = "fonttools" },
|
||||
{ name = "kiwisolver" },
|
||||
{ name = "numpy" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pillow" },
|
||||
{ name = "pyparsing" },
|
||||
{ name = "python-dateutil" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/63/1b/4be5be87d43d327a0cf4de1a56e86f7f84c89312452406cf122efe2839e6/matplotlib-3.10.9.tar.gz", hash = "sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358", size = 34811233, upload-time = "2026-04-24T00:14:13.539Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/35/c6/5581e26c72233ebb2a2a6fed2d24fb7c66b4700120b813f51b0555acf0b6/matplotlib-3.10.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1", size = 8319908, upload-time = "2026-04-24T00:12:21.323Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/18/4880dd762e40cd360c1bf06e890c5a97b997e91cb324602b1a19950ad5ce/matplotlib-3.10.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320", size = 8216016, upload-time = "2026-04-24T00:12:23.4Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/91/d024616abdba99e83120e07a20658976f6a343646710760c4a51df126029/matplotlib-3.10.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285", size = 8789336, upload-time = "2026-04-24T00:12:26.096Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/04/030a2f61ef2158f5e4c259487a92ac877732499fb33d871585d89e03c42d/matplotlib-3.10.9-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2", size = 9604602, upload-time = "2026-04-24T00:12:29.052Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/c2/541e4d09d87bb6b5830fc28b4c887a9a8cf4e1c6cee698a8c05552ae2003/matplotlib-3.10.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf", size = 9670966, upload-time = "2026-04-24T00:12:32.131Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/a1/4571fc46e7702de8d0c2dc54ad1b2f8e29328dea3ee90831181f7353d93c/matplotlib-3.10.9-cp312-cp312-win_amd64.whl", hash = "sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6", size = 8217462, upload-time = "2026-04-24T00:12:35.226Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/d0/2269edb12aa30c13c8bcc9382892e39943ce1d28aab4ec296e0381798e81/matplotlib-3.10.9-cp312-cp312-win_arm64.whl", hash = "sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42", size = 8136688, upload-time = "2026-04-24T00:12:37.442Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mlx"
|
||||
version = "0.31.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mlx-metal", marker = "sys_platform == 'darwin'" },
|
||||
]
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/47/5f33906cb03d6a378a697cd2d2641a26b37dea17ee3d9124d7e39e8eca01/mlx-0.31.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:e5067aaf2be1f3d7bba5be52348775804f111173c1ed04639618fd713b1a530f", size = 584863, upload-time = "2026-04-22T03:14:38.211Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/e7/a851a451b1327af9fb4df3991b9ae87d066b6f6630e854af55c288b0995a/mlx-0.31.2-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:edb9797db7d852477ca1c99708058654ee860d4148fe5765f0d55528e2b1aa22", size = 584860, upload-time = "2026-04-22T03:14:39.746Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/15/0d1dc0597644e5e7b011ca954ba0c47e13cd880a3b909b0c3f1b4d8bf8f1/mlx-0.31.2-cp312-cp312-macosx_26_0_arm64.whl", hash = "sha256:51ca102db641b01e7cb083ce8ecb580e281530a141a7ca12544bb370641630ae", size = 584887, upload-time = "2026-04-22T03:14:41.585Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/c3/00664239a98e8bd614733c4182cd402d2bacad2d7f79eca66562ac406870/mlx-0.31.2-cp312-cp312-manylinux_2_35_aarch64.whl", hash = "sha256:117c7583cae0ca107cd53c591cc34f8e75f97a505aa47088844b7dc0fc69dc67", size = 627863, upload-time = "2026-04-22T03:14:43.326Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/7b/af6cd73a79772af6f19eab2cb4c48eda23a9294d1650a4c1269a9996e532/mlx-0.31.2-cp312-cp312-manylinux_2_35_x86_64.whl", hash = "sha256:99572133181481640a8bf8d449daf083816d0af3ee050c8adfc5bf45ceca91c6", size = 685090, upload-time = "2026-04-22T03:14:45.058Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mlx-metal"
|
||||
version = "0.31.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/69/fe3b783ebe999f3118234e1e940feb622518bfb1dea6ac5d13b1d36a8449/mlx_metal-0.31.2-py3-none-macosx_14_0_arm64.whl", hash = "sha256:b25385bcee18fc194092255b8b53b9a3d8489eb650e59160f1b57aadd07aa2dc", size = 40055588, upload-time = "2026-04-22T03:14:14.43Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/5d/4c690d5b93c30ba002656c37363159d978705bf8eb801b8481840fb942c2/mlx_metal-0.31.2-py3-none-macosx_15_0_arm64.whl", hash = "sha256:e9d4e5fce6ca10a87a0e388597f99519ad594d09e674708b5312bd8bd4f5997d", size = 40053220, upload-time = "2026-04-22T03:14:18.048Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/82/11fd62a8d7a3e96e5c43220b17de0151e3f10101f8bb3b865f5bd9cdd074/mlx_metal-0.31.2-py3-none-macosx_26_0_arm64.whl", hash = "sha256:84ffb60ee503f03eb684f5fb168d5cff31e2a16b7f27c1731eaf7662bd6e9b46", size = 55792151, upload-time = "2026-04-22T03:14:22.059Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -751,18 +604,21 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "1.26.4"
|
||||
version = "2.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129, upload-time = "2024-02-06T00:26:44.495Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901, upload-time = "2024-02-05T23:55:32.801Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868, upload-time = "2024-02-05T23:55:56.28Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109, upload-time = "2024-02-05T23:56:20.368Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613, upload-time = "2024-02-05T23:56:56.054Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172, upload-time = "2024-02-05T23:57:21.56Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643, upload-time = "2024-02-05T23:57:56.585Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803, upload-time = "2024-02-05T23:58:08.963Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754, upload-time = "2024-02-05T23:58:36.364Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/2a/3d7b5ac8aac24feaf9ad7ed58f45b0bbc06d37e4338ae84c9f2298b570f9/numpy-2.4.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1", size = 16689119, upload-time = "2026-05-18T23:33:54.065Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/12/92c4c131527599e8288d6918e888d88726f84d805d784b771f32408aeaef/numpy-2.4.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb", size = 14699246, upload-time = "2026-05-18T23:33:57.621Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/fe/c0a6b7b2ca128a8fb228575147073b660656734b8ebe4d76c8fd748dcc79/numpy-2.4.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41", size = 5204410, upload-time = "2026-05-18T23:34:00.302Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/d4/9770d14ba719432bb90a421bfd443872ed0f70f7264b64bec12ea363d5fd/numpy-2.4.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698", size = 6551240, upload-time = "2026-05-18T23:34:02.852Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/c6/50a46a6205feba2343f1d6d17438107c5dc491ed1c736e6ea68689fd906b/numpy-2.4.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f", size = 15671012, upload-time = "2026-05-18T23:34:05.485Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/60/14115e6364fa676c5397c2ad3004e527e9aa487abf5d0706ec81bbd08529/numpy-2.4.6-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853", size = 16645538, upload-time = "2026-05-18T23:34:09.265Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/c5/693cbe59e57db94d2231fa519ca3978dc9e19da5a8f088588f5c6e947ff2/numpy-2.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a", size = 17020706, upload-time = "2026-05-18T23:34:13.053Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/fc/85b7c4eff9b4966ade25c2273cf7e7012e92366c032058653934b37de044/numpy-2.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2", size = 18368541, upload-time = "2026-05-18T23:34:17.024Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/81/e1b27545deedce7f4a0b348618c6b62d74e36a4dc9ccd42f3eb2f85eee32/numpy-2.4.6-cp312-cp312-win32.whl", hash = "sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45", size = 5962825, upload-time = "2026-05-18T23:34:20.3Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/ca/feab00bd44aa5fe1ad2c18f08b4d3bb92e26484b0b1d1443897809ed528c/numpy-2.4.6-cp312-cp312-win_amd64.whl", hash = "sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751", size = 12321687, upload-time = "2026-05-18T23:34:23.095Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/cf/5a6d34850a39d1093558564f77ee8e8e0bee5061151b8f05a55711001ec7/numpy-2.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8", size = 10221482, upload-time = "2026-05-18T23:34:25.876Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -911,32 +767,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/94/1843518e420fa3ed6919835845df698c7e27e183cb997394e4a670973a65/omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b", size = 79500, upload-time = "2022-12-08T20:59:19.686Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opencv-python"
|
||||
version = "4.11.0.86"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "numpy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/17/06/68c27a523103dad5837dc5b87e71285280c4f098c60e4fe8a8db6486ab09/opencv-python-4.11.0.86.tar.gz", hash = "sha256:03d60ccae62304860d232272e4a4fda93c39d595780cb40b161b310244b736a4", size = 95171956, upload-time = "2025-01-16T13:52:24.737Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/05/4d/53b30a2a3ac1f75f65a59eb29cf2ee7207ce64867db47036ad61743d5a23/opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:432f67c223f1dc2824f5e73cdfcd9db0efc8710647d4e813012195dc9122a52a", size = 37326322, upload-time = "2025-01-16T13:52:25.887Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/84/0a67490741867eacdfa37bc18df96e08a9d579583b419010d7f3da8ff503/opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:9d05ef13d23fe97f575153558653e2d6e87103995d54e6a35db3f282fe1f9c66", size = 56723197, upload-time = "2025-01-16T13:55:21.222Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/bd/29c126788da65c1fb2b5fb621b7fed0ed5f9122aa22a0868c5e2c15c6d23/opencv_python-4.11.0.86-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b92ae2c8852208817e6776ba1ea0d6b1e0a1b5431e971a2a0ddd2a8cc398202", size = 42230439, upload-time = "2025-01-16T13:51:35.822Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/8b/90eb44a40476fa0e71e05a0283947cfd74a5d36121a11d926ad6f3193cc4/opencv_python-4.11.0.86-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b02611523803495003bd87362db3e1d2a0454a6a63025dc6658a9830570aa0d", size = 62986597, upload-time = "2025-01-16T13:52:08.836Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/d7/1d5941a9dde095468b288d989ff6539dd69cd429dbf1b9e839013d21b6f0/opencv_python-4.11.0.86-cp37-abi3-win32.whl", hash = "sha256:810549cb2a4aedaa84ad9a1c92fbfdfc14090e2749cedf2c1589ad8359aa169b", size = 29384337, upload-time = "2025-01-16T13:52:13.549Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/7d/f1c30a92854540bf789e9cd5dde7ef49bbe63f855b85a2e6b3db8135c591/opencv_python-4.11.0.86-cp37-abi3-win_amd64.whl", hash = "sha256:085ad9b77c18853ea66283e98affefe2de8cc4c1f43eda4c100cf9b2721142ec", size = 39488044, upload-time = "2025-01-16T13:52:21.928Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "overrides"
|
||||
version = "7.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812, upload-time = "2024-01-27T21:01:33.423Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832, upload-time = "2024-01-27T21:01:31.393Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "26.2"
|
||||
@@ -948,7 +778,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "peft"
|
||||
version = "0.13.2"
|
||||
version = "0.19.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "accelerate" },
|
||||
@@ -962,9 +792,9 @@ dependencies = [
|
||||
{ name = "tqdm" },
|
||||
{ name = "transformers" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/97/e1/aab80b861b4c18e85482940d504b3a7ee525bdf6ed93a1a2871881a180f1/peft-0.13.2.tar.gz", hash = "sha256:0e0cbd40ebdf5fe4ea79f255880d02f96712d18899509369a2cc5768ad46d672", size = 350390, upload-time = "2024-10-11T11:42:21.874Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/86/cf/037f1e3d5186496c05513a6754639e2dab3038a05f384284d49a9bd06a2d/peft-0.19.1.tar.gz", hash = "sha256:0d97542fe96dcdaa20d3b81c06f26f988618f416a73544ab23c3618ccb674a40", size = 763738, upload-time = "2026-04-16T15:46:45.105Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/78/9d/5f95bfb298c8d3b4e3a107701f9a4e7774a0d4d1f8eb0c9d5420b80f7c9d/peft-0.13.2-py3-none-any.whl", hash = "sha256:d4e0951ec78eac11c45a051801c569913436888c578d48e5ce86996b715bc6ef", size = 320731, upload-time = "2024-10-11T11:42:18.905Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/b6/f54d676ed93cc2dd2234c3b172ea9c8c3d7d29361e66b1b23dec57a67465/peft-0.19.1-py3-none-any.whl", hash = "sha256:2113f72a81621b5913ef28f9022204c742df111890c5f49d812716a4a301e356", size = 680692, upload-time = "2026-04-16T15:46:42.886Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -986,15 +816,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/10/e1/542a474affab20fd4a0f1836cb234e8493519da6b76899e30bcc5d990b8b/pillow-12.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414", size = 2463612, upload-time = "2026-04-01T14:43:39.421Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "4.9.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400, upload-time = "2026-04-09T00:04:10.812Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348, upload-time = "2026-04-09T00:04:09.463Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.6.0"
|
||||
@@ -1082,51 +903,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.13.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "annotated-types" },
|
||||
{ name = "pydantic-core" },
|
||||
{ name = "typing-extensions" },
|
||||
{ name = "typing-inspection" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic-core"
|
||||
version = "2.46.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/8c/af022f0af448d7747c5154288d46b5f2bc5f17366eaa0e23e9aa04d59f3b/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2", size = 2106158, upload-time = "2026-05-06T13:38:57.215Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/95/6195171e385007300f0f5574592e467c568becce2d937a0b6804f218bc49/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f", size = 1951724, upload-time = "2026-05-06T13:37:02.697Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742, upload-time = "2026-05-06T13:37:09.448Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418, upload-time = "2026-05-06T13:37:38.234Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274, upload-time = "2026-05-06T13:38:27.753Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940, upload-time = "2026-05-06T13:38:05.353Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516, upload-time = "2026-05-06T13:39:10.577Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854, upload-time = "2026-05-06T13:40:22.59Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306, upload-time = "2026-05-06T13:40:10.666Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044, upload-time = "2026-05-06T13:40:43.231Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133, upload-time = "2026-05-06T13:39:57.365Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464, upload-time = "2026-05-06T13:38:06.976Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/bd/6f2fc8188f31bf10590f1e98e7b306336161fac930a8c514cd7bd828c7dc/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894", size = 1974823, upload-time = "2026-05-06T13:40:47.985Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/8c/985c1d41ea1107c2534abd9870e4ed5c8e7669b5c308297835c001e7a1c4/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89", size = 2072919, upload-time = "2026-05-06T13:39:21.153Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/ba/f463d006e0c47373ca7ec5e1a261c59dc01ef4d62b2657af925fb0deee3a/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a", size = 2027604, upload-time = "2026-05-06T13:39:03.753Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/1d/8987ad40f65ae1432753072f214fb5c74fe47ffbd0698bb9cbbb585664f8/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7", size = 2095527, upload-time = "2026-05-06T13:39:52.283Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/d3/84c282a7eee1d3ac4c0377546ef5a1ea436ce26840d9ac3b7ed54a377507/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df", size = 1936024, upload-time = "2026-05-06T13:40:15.671Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/ca/eac61596cdeb4d7e174d3dc0bd8a6238f14f75f97a24e7b7db4c7e7340a0/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526", size = 1990696, upload-time = "2026-05-06T13:38:34.717Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/c3/7c8b240552251faf6b3a957db200fcfbbcec36763c050428b601e0c9b83b/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0", size = 2147590, upload-time = "2026-05-06T13:39:29.883Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.20.0"
|
||||
@@ -1136,15 +912,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyparsing"
|
||||
version = "3.3.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "9.0.3"
|
||||
@@ -1161,57 +928,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-coreml-stable-diffusion"
|
||||
version = "1.1.0"
|
||||
source = { git = "https://github.com/apple/ml-stable-diffusion.git?rev=e5d960c41a6a4ab200b8db379194127607b1c590#e5d960c41a6a4ab200b8db379194127607b1c590" }
|
||||
dependencies = [
|
||||
{ name = "coremltools" },
|
||||
{ name = "diffusers" },
|
||||
{ name = "diffusionkit" },
|
||||
{ name = "huggingface-hub" },
|
||||
{ name = "invisible-watermark" },
|
||||
{ name = "matplotlib" },
|
||||
{ name = "numpy" },
|
||||
{ name = "pytest" },
|
||||
{ name = "safetensors" },
|
||||
{ name = "scikit-learn" },
|
||||
{ name = "scipy" },
|
||||
{ name = "torch" },
|
||||
{ name = "transformers" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.9.0.post0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "six" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pywavelets"
|
||||
version = "1.8.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "numpy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/48/45/bfaaab38545a33a9f06c61211fc3bea2e23e8a8e00fedeb8e57feda722ff/pywavelets-1.8.0.tar.gz", hash = "sha256:f3800245754840adc143cbc29534a1b8fc4b8cff6e9d403326bd52b7bb5c35aa", size = 3935274, upload-time = "2024-12-04T19:54:20.593Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/8b/4870f11559307416470158a5aa6f61e5c2a910f1645a7a836ffae580b7ad/pywavelets-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3f431c9e2aff1a2240765eff5e804975d0fcc24c82d6f3d4271243f228e5963b", size = 4326187, upload-time = "2024-12-04T19:53:35.19Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/35/66835d889fd7fbf3119c7a9bd9d9bd567fc0bb603dfba408e9226db7cb44/pywavelets-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e39b0e2314e928cb850ee89b9042733a10ea044176a495a54dc84d2c98407a51", size = 4295428, upload-time = "2024-12-04T19:53:36.962Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/1c/42e5130226538c70d4bbbaee00eb1bc06ec3287f7ea43d5fcf85bfc761ce/pywavelets-1.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cae701117f5c7244b7c8d48b9e92a0289637cdc02a9c205e8be83361f0c11fae", size = 4421259, upload-time = "2024-12-04T19:53:39.119Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/c5/1ce93657432e22a5debc21e8b52ec6980f819ecb7fa727bb86744224d967/pywavelets-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:649936baee933e80083788e0adc4d8bc2da7cdd8b10464d3b113475be2cc5308", size = 4447650, upload-time = "2024-12-04T19:53:41.589Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/d6/b54ef30daca71824f811f9d2322a978b0a58d27674b8e3af6520f67e9ec6/pywavelets-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8c68e9d072c536bc646e8bdce443bb1826eeb9aa21b2cb2479a43954dea692a3", size = 4448538, upload-time = "2024-12-04T19:53:44.308Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/8c/1688b790e55674667ad644262f174405c2c9873cb13e773432e78b1b33e4/pywavelets-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:63f67fa2ee1610445de64f746fb9c1df31980ad13d896ea2331fc3755f49b3ae", size = 4485228, upload-time = "2024-12-04T19:53:46.778Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/9b/69de31c3b663dadd76d1da6bf8af68d8cefff55df8e880fe96a94bb8c9ac/pywavelets-1.8.0-cp312-cp312-win32.whl", hash = "sha256:4b3c2ab669c91e3474fd63294355487b7dd23f0b51d32f811327ddf3546f4f3d", size = 4134850, upload-time = "2024-12-04T19:53:49.101Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/88/9e2aa9d5fde08bfc0fb18ffb1b5307c1ed49c24930b4147e5f48571a7251/pywavelets-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:810a23a631da596fef7196ddec49b345b1aab13525bb58547eeebe1769edbbc1", size = 4210786, upload-time = "2024-12-04T19:53:51.546Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.3"
|
||||
@@ -1269,6 +985,19 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rich"
|
||||
version = "15.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "markdown-it-py" },
|
||||
{ name = "pygments" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "safetensors"
|
||||
version = "0.7.0"
|
||||
@@ -1291,25 +1020,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/e6/ec8471c8072382cb91233ba7267fd931219753bb43814cbc71757bfd4dab/safetensors-0.7.0-cp38-abi3-win_amd64.whl", hash = "sha256:d1239932053f56f3456f32eb9625590cc7582e905021f94636202a864d470755", size = 341380, upload-time = "2025-11-19T15:18:44.427Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scikit-learn"
|
||||
version = "1.7.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "joblib" },
|
||||
{ name = "numpy" },
|
||||
{ name = "scipy" },
|
||||
{ name = "threadpoolctl" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/98/c2/a7855e41c9d285dfe86dc50b250978105dce513d6e459ea66a6aeb0e1e0c/scikit_learn-1.7.2.tar.gz", hash = "sha256:20e9e49ecd130598f1ca38a1d85090e1a600147b9c02fa6f15d69cb53d968fda", size = 7193136, upload-time = "2025-09-09T08:21:29.075Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/aa/3996e2196075689afb9fce0410ebdb4a09099d7964d061d7213700204409/scikit_learn-1.7.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8d91a97fa2b706943822398ab943cde71858a50245e31bc71dba62aab1d60a96", size = 9259818, upload-time = "2025-09-09T08:20:43.19Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/5d/779320063e88af9c4a7c2cf463ff11c21ac9c8bd730c4a294b0000b666c9/scikit_learn-1.7.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:acbc0f5fd2edd3432a22c69bed78e837c70cf896cd7993d71d51ba6708507476", size = 8636997, upload-time = "2025-09-09T08:20:45.468Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/d0/0c577d9325b05594fdd33aa970bf53fb673f051a45496842caee13cfd7fe/scikit_learn-1.7.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5bf3d930aee75a65478df91ac1225ff89cd28e9ac7bd1196853a9229b6adb0b", size = 9478381, upload-time = "2025-09-09T08:20:47.982Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/70/8bf44b933837ba8494ca0fc9a9ab60f1c13b062ad0197f60a56e2fc4c43e/scikit_learn-1.7.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d6e9deed1a47aca9fe2f267ab8e8fe82ee20b4526b2c0cd9e135cea10feb44", size = 9300296, upload-time = "2025-09-09T08:20:50.366Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/99/ed35197a158f1fdc2fe7c3680e9c70d0128f662e1fee4ed495f4b5e13db0/scikit_learn-1.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:6088aa475f0785e01bcf8529f55280a3d7d298679f50c0bb70a2364a82d0b290", size = 8731256, upload-time = "2025-09-09T08:20:52.627Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scipy"
|
||||
version = "1.15.3"
|
||||
@@ -1346,19 +1056,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/02/c5e3bc518655d714622bec87d83db9cdba1cd0619a4a04e2109751c4f47f/sentencepiece-0.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:daeb5e9e9fcad012324807856113708614d534f596d5008638eb9b40112cd9e4", size = 1033923, upload-time = "2025-08-12T06:59:51.952Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-sdk"
|
||||
version = "2.60.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "certifi" },
|
||||
{ name = "urllib3" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/54/a2/2e6c090db384cc515069f4f85542bd5baf6786852073020ea73d4a76d3ea/sentry_sdk-2.60.0.tar.gz", hash = "sha256:0bd25e54e78ca02d0be512529fa644bbbf9e8470d7b26371294012d4ca93c978", size = 452946, upload-time = "2026-05-13T13:34:52.516Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/29/41/f2b800b7f12a05dd48c2a6280d4dd812d1425fc66ed3fe3fd99420c41d1a/sentry_sdk-2.60.0-py3-none-any.whl", hash = "sha256:28a536c03291c8bcb363cf35c611b32738ec118ff64d8d6383b096448ac4c803", size = 475616, upload-time = "2026-05-13T13:34:50.259Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "81.0.0"
|
||||
@@ -1369,21 +1066,12 @@ wheels = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.17.0"
|
||||
name = "shellingham"
|
||||
version = "1.5.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smmap"
|
||||
version = "5.0.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1f/ea/49c993d6dfdd7338c9b1000a0f36817ed7ec84577ae2e52f890d1a4ff909/smmap-5.0.3.tar.gz", hash = "sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c", size = 22506, upload-time = "2026-03-09T03:43:26.1Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl", hash = "sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f", size = 24390, upload-time = "2026-03-09T03:43:24.361Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1434,45 +1122,30 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tabulate"
|
||||
version = "0.10.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/46/58/8c37dea7bbf769b20d58e7ace7e5edfe65b849442b00ffcdd56be88697c6/tabulate-0.10.0.tar.gz", hash = "sha256:e2cfde8f79420f6deeffdeda9aaec3b6bc5abce947655d17ac662b126e48a60d", size = 91754, upload-time = "2026-03-04T18:55:34.402Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl", hash = "sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3", size = 39814, upload-time = "2026-03-04T18:55:31.284Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "threadpoolctl"
|
||||
version = "3.6.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokenizers"
|
||||
version = "0.19.1"
|
||||
version = "0.22.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "huggingface-hub" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/48/04/2071c150f374aab6d5e92aaec38d0f3c368d227dd9e0469a1f0966ac68d1/tokenizers-0.19.1.tar.gz", hash = "sha256:ee59e6680ed0fdbe6b724cf38bd70400a0c1dd623b07ac729087270caeac88e3", size = 321039, upload-time = "2024-04-17T21:40:41.849Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/73/6f/f80cfef4a312e1fb34baf7d85c72d4411afde10978d4657f8cdd811d3ccc/tokenizers-0.22.2.tar.gz", hash = "sha256:473b83b915e547aa366d1eee11806deaf419e17be16310ac0a14077f1e28f917", size = 372115, upload-time = "2026-01-05T10:45:15.988Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/63/90/2890cd096898dcdb596ee172cde40c0f54a9cf43b0736aa260a5501252af/tokenizers-0.19.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:621d670e1b1c281a1c9698ed89451395d318802ff88d1fc1accff0867a06f153", size = 2530580, upload-time = "2024-04-17T21:37:10.688Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/d1/f4e1e950adb36675dfd8f9d0f4be644f3f3aaf22a5677a4f5c81282b662e/tokenizers-0.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d924204a3dbe50b75630bd16f821ebda6a5f729928df30f582fb5aade90c818a", size = 2436682, upload-time = "2024-04-17T21:37:12.966Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/30/89b321a16c58d233e301ec15072c0d3ed5014825e72da98604cd3ab2fba1/tokenizers-0.19.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4f3fefdc0446b1a1e6d81cd4c07088ac015665d2e812f6dbba4a06267d1a2c95", size = 3693494, upload-time = "2024-04-17T21:37:14.755Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/40/fa899f32de483500fbc78befd378fd7afba4270f17db707d1a78c0a4ddc3/tokenizers-0.19.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9620b78e0b2d52ef07b0d428323fb34e8ea1219c5eac98c2596311f20f1f9266", size = 3566541, upload-time = "2024-04-17T21:37:17.067Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/14/e7da32ae5fb4971830f1ef335932fae3fa57e76b537e852f146c850aefdf/tokenizers-0.19.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04ce49e82d100594715ac1b2ce87d1a36e61891a91de774755f743babcd0dd52", size = 3430792, upload-time = "2024-04-17T21:37:19.055Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/4b/aae61bdb6ab584d2612170801703982ee0e35f8b6adacbeefe5a3b277621/tokenizers-0.19.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5c2ff13d157afe413bf7e25789879dd463e5a4abfb529a2d8f8473d8042e28f", size = 3962812, upload-time = "2024-04-17T21:37:21.008Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/b6/f7b7ef89c4da7b20256e6eab23d3835f05d1ca8f451d31c16cbfe3cd9eb6/tokenizers-0.19.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3174c76efd9d08f836bfccaca7cfec3f4d1c0a4cf3acbc7236ad577cc423c840", size = 4024688, upload-time = "2024-04-17T21:37:23.659Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/54/12047a69f5b382d7ee72044dc89151a2dd0d13b2c9bdcc22654883704d31/tokenizers-0.19.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c9d5b6c0e7a1e979bec10ff960fae925e947aab95619a6fdb4c1d8ff3708ce3", size = 3610961, upload-time = "2024-04-17T21:37:26.234Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/52/b7/1e8a913d18ac28feeda42d4d2d51781874398fb59cd1c1e2653a4b5742ed/tokenizers-0.19.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a179856d1caee06577220ebcfa332af046d576fb73454b8f4d4b0ba8324423ea", size = 9631367, upload-time = "2024-04-17T21:37:28.752Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/3d/2284f6d99f8f21d09352b88b8cfefa24ab88468d962aeb0aa15c20d76b32/tokenizers-0.19.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:952b80dac1a6492170f8c2429bd11fcaa14377e097d12a1dbe0ef2fb2241e16c", size = 9950121, upload-time = "2024-04-17T21:37:31.741Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/94/ec3369dbc9b7200c14c8c7a1a04c78b7a7398d0c001e1b7d1ffe30eb93a0/tokenizers-0.19.1-cp312-none-win32.whl", hash = "sha256:01d62812454c188306755c94755465505836fd616f75067abcae529c35edeb57", size = 2044069, upload-time = "2024-04-17T21:37:35.672Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/97/80bff6937e0c67d30c0facacd4f0bcf4254e581aa4995c73cef8c8640e56/tokenizers-0.19.1-cp312-none-win_amd64.whl", hash = "sha256:b70bfbe3a82d3e3fb2a5e9b22a39f8d1740c96c68b6ace0086b39074f08ab89a", size = 2214527, upload-time = "2024-04-17T21:37:39.19Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/97/5dbfabf04c7e348e655e907ed27913e03db0923abb5dfdd120d7b25630e1/tokenizers-0.22.2-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:544dd704ae7238755d790de45ba8da072e9af3eea688f698b137915ae959281c", size = 3100275, upload-time = "2026-01-05T10:41:02.158Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/47/174dca0502ef88b28f1c9e06b73ce33500eedfac7a7692108aec220464e7/tokenizers-0.22.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1e418a55456beedca4621dbab65a318981467a2b188e982a23e117f115ce5001", size = 2981472, upload-time = "2026-01-05T10:41:00.276Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/84/7990e799f1309a8b87af6b948f31edaa12a3ed22d11b352eaf4f4b2e5753/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2249487018adec45d6e3554c71d46eb39fa8ea67156c640f7513eb26f318cec7", size = 3290736, upload-time = "2026-01-05T10:40:32.165Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/59/09d0d9ba94dcd5f4f1368d4858d24546b4bdc0231c2354aa31d6199f0399/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25b85325d0815e86e0bac263506dd114578953b7b53d7de09a6485e4a160a7dd", size = 3168835, upload-time = "2026-01-05T10:40:38.847Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/50/b3ebb4243e7160bda8d34b731e54dd8ab8b133e50775872e7a434e524c28/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfb88f22a209ff7b40a576d5324bf8286b519d7358663db21d6246fb17eea2d5", size = 3521673, upload-time = "2026-01-05T10:40:56.614Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/fa/89f4cb9e08df770b57adb96f8cbb7e22695a4cb6c2bd5f0c4f0ebcf33b66/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c774b1276f71e1ef716e5486f21e76333464f47bece56bbd554485982a9e03e", size = 3724818, upload-time = "2026-01-05T10:40:44.507Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/04/ca2363f0bfbe3b3d36e95bf67e56a4c88c8e3362b658e616d1ac185d47f2/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df6c4265b289083bf710dff49bc51ef252f9d5be33a45ee2bed151114a56207b", size = 3379195, upload-time = "2026-01-05T10:40:51.139Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/76/932be4b50ef6ccedf9d3c6639b056a967a86258c6d9200643f01269211ca/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:369cc9fc8cc10cb24143873a0d95438bb8ee257bb80c71989e3ee290e8d72c67", size = 3274982, upload-time = "2026-01-05T10:40:58.331Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/28/5f9f5a4cc211b69e89420980e483831bcc29dade307955cc9dc858a40f01/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:29c30b83d8dcd061078b05ae0cb94d3c710555fbb44861139f9f83dcca3dc3e4", size = 9478245, upload-time = "2026-01-05T10:41:04.053Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/fb/66e2da4704d6aadebf8cb39f1d6d1957df667ab24cff2326b77cda0dcb85/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:37ae80a28c1d3265bb1f22464c856bd23c02a05bb211e56d0c5301a435be6c1a", size = 9560069, upload-time = "2026-01-05T10:45:10.673Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/04/fed398b05caa87ce9b1a1bb5166645e38196081b225059a6edaff6440fac/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:791135ee325f2336f498590eb2f11dc5c295232f288e75c99a36c5dbce63088a", size = 9899263, upload-time = "2026-01-05T10:45:12.559Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/a1/d62dfe7376beaaf1394917e0f8e93ee5f67fea8fcf4107501db35996586b/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38337540fbbddff8e999d59970f3c6f35a82de10053206a7562f1ea02d046fa5", size = 10033429, upload-time = "2026-01-05T10:45:14.333Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/18/a545c4ea42af3df6effd7d13d250ba77a0a86fb20393143bbb9a92e434d4/tokenizers-0.22.2-cp39-abi3-win32.whl", hash = "sha256:a6bf3f88c554a2b653af81f3204491c818ae2ac6fbc09e76ef4773351292bc92", size = 2502363, upload-time = "2026-01-05T10:45:20.593Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/65/71/0670843133a43d43070abeb1949abfdef12a86d490bea9cd9e18e37c5ff7/tokenizers-0.22.2-cp39-abi3-win_amd64.whl", hash = "sha256:c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48", size = 2747786, upload-time = "2026-01-05T10:45:18.411Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/f4/0de46cfa12cdcbcd464cc59fde36912af405696f687e53a091fb432f694c/tokenizers-0.22.2-cp39-abi3-win_arm64.whl", hash = "sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc", size = 2612133, upload-time = "2026-01-05T10:45:17.232Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1574,23 +1247,22 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "transformers"
|
||||
version = "4.44.2"
|
||||
version = "5.9.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "filelock" },
|
||||
{ name = "huggingface-hub" },
|
||||
{ name = "numpy" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "regex" },
|
||||
{ name = "requests" },
|
||||
{ name = "safetensors" },
|
||||
{ name = "tokenizers" },
|
||||
{ name = "tqdm" },
|
||||
{ name = "typer" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f8/a3/81de49357a3c6ac4421d48d9662b53293838f217baf3f3bb9eb55f89fab6/transformers-4.44.2.tar.gz", hash = "sha256:36aa17cc92ee154058e426d951684a2dab48751b35b49437896f898931270826", size = 8110312, upload-time = "2024-08-22T16:56:33.522Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/51/58/7f843608f2e8421f86bb97060b54649be6239ec612b82bf9d41e65c26c00/transformers-5.9.0.tar.gz", hash = "sha256:25997cb8fa6053533171634b6162d7df54346530ec2aa9b42bb834e63668c842", size = 8642240, upload-time = "2026-05-20T14:50:49.278Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/75/35/07c9879163b603f0e464b0f6e6e628a2340cfc7cdc5ca8e7d52d776710d4/transformers-4.44.2-py3-none-any.whl", hash = "sha256:1c02c65e7bfa5e52a634aff3da52138b583fc6f263c1f28d547dc144ba3d412d", size = 9465369, upload-time = "2024-08-22T16:56:29.207Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/ca/2eaa5359f2ccb8c2e1656bc26305ad0cf438aa392ce4b29ae67a315c186e/transformers-5.9.0-py3-none-any.whl", hash = "sha256:1d19509bcff7028ebc6b277d71caa712e8353778463d38764237d14b42b52788", size = 10787648, upload-time = "2026-05-20T14:50:45.337Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1604,6 +1276,21 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/24/5f/950fb373bf9c01ad4eb5a8cd5eaf32cdf9e238c02f9293557a2129b9c4ac/triton-3.3.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9999e83aba21e1a78c1f36f21bce621b77bcaa530277a50484a7cb4a822f6e43", size = 155669138, upload-time = "2025-05-29T23:39:51.771Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typer"
|
||||
version = "0.25.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "annotated-doc" },
|
||||
{ name = "click" },
|
||||
{ name = "rich" },
|
||||
{ name = "shellingham" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e4/51/9aed62104cea109b820bbd6c14245af756112017d309da813ef107d42e7e/typer-0.25.1.tar.gz", hash = "sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc", size = 122276, upload-time = "2026-04-30T19:32:16.964Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl", hash = "sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89", size = 58409, upload-time = "2026-04-30T19:32:18.271Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.15.0"
|
||||
@@ -1613,18 +1300,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-inspection"
|
||||
version = "0.4.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.7.0"
|
||||
@@ -1634,44 +1309,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wadler-lindig"
|
||||
version = "0.1.7"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1e/67/cbae4bf7683a64755c2c1778c418fea96d00e34395bb91743f08bd951571/wadler_lindig-0.1.7.tar.gz", hash = "sha256:81d14d3fe77d441acf3ebd7f4aefac20c74128bf460e84b512806dccf7b2cd55", size = 15842, upload-time = "2025-06-18T07:00:42.843Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/96/04e7b441807b26b794da5b11e59ed7f83b2cf8af202bd7eba8ad2fa6046e/wadler_lindig-0.1.7-py3-none-any.whl", hash = "sha256:e3ec83835570fd0a9509f969162aeb9c65618f998b1f42918cfc8d45122fe953", size = 20516, upload-time = "2025-06-18T07:00:41.684Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wandb"
|
||||
version = "0.27.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "click" },
|
||||
{ name = "gitpython" },
|
||||
{ name = "packaging" },
|
||||
{ name = "platformdirs" },
|
||||
{ name = "protobuf" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "requests" },
|
||||
{ name = "sentry-sdk" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8e/31/fe53d06b75ef0a7f2f0ee5931a89f7aedc27d233840b1839616860fed256/wandb-0.27.0.tar.gz", hash = "sha256:579e75300173059f9334e1f513a79ef15f6d9ea5c74e20d695633648cdd02031", size = 41090732, upload-time = "2026-05-14T03:44:08.894Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/5e/2c199e70e636ecfd217cde0bc7469f4511e1d03d0685eb92bfdfce391430/wandb-0.27.0-py3-none-macosx_12_0_arm64.whl", hash = "sha256:c156be4851485f3c4160cb6eb2e8991b4cdeffbccefc5636d33cf5e254847365", size = 24886476, upload-time = "2026-05-14T03:43:27.569Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/cd/a617c871cd304a9804e56a7ec2ec2c65685bf0091a2b9f91910175a149e2/wandb-0.27.0-py3-none-macosx_12_0_x86_64.whl", hash = "sha256:20179f38afb0158859a4141d29ac650d3fdbd0cf801a74ce25565c934f03776c", size = 26045779, upload-time = "2026-05-14T03:43:31.999Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/0a/d3f159a201530b84b72ca5f98c68d1f351c2d9a1864558ed76c811407fae/wandb-0.27.0-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:626497d7975fa898d0a4a239da7a510483495ca3514510dbe75004a25963af4d", size = 25480764, upload-time = "2026-05-14T03:43:35.922Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/6a/8721fcdf71d42639191040a77a585d2982402b1754700cb2ecfc2ca1470a/wandb-0.27.0-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:f772da7005cc26a2a32b729a16982a583dc68b3d493df6a09d0aa5c5ca5a2060", size = 27256204, upload-time = "2026-05-14T03:43:39.765Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/5e/279d167ba79fb7a8a43401c9f25efd0f6663ee9bd1eaf5a8578530198888/wandb-0.27.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:63acfc5b994e4a90e4a2fbdee6d45e664da3dd865bb1419942c8995c06c41cf1", size = 25647469, upload-time = "2026-05-14T03:43:44.817Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/51/a69ac59300e3c813939d0764348959ed2a21e14c668cb1cebcb04010da6a/wandb-0.27.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:17aae6e4a88cd05c00ea8f546220918e3ebb6f8c1c36b70ef04a5ac75f0d7160", size = 27599005, upload-time = "2026-05-14T03:43:50.926Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/40/bf510c8758727df020f83b717ebc1fcc1739ed7f6ae1796ebef60bf6f592/wandb-0.27.0-py3-none-win32.whl", hash = "sha256:0bd5659417e386bf6538b5e2ffe6885774c6197f0e4853bfed517d5b0db457f1", size = 25036164, upload-time = "2026-05-14T03:43:54.839Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/ff/69f88e7d90c22b79bcb911143c13e59742ee192080b21015ff83a5a1f60a/wandb-0.27.0-py3-none-win_amd64.whl", hash = "sha256:89d584b73166eecee96fb446f18d0e45b1aa45aba6a3696296f3f06d7454516b", size = 25036170, upload-time = "2026-05-14T03:43:59.227Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/38/f7efd7a87297a55c7e9a331a1dbb5b19e54aeacc11fe6f43f8636a73987c/wandb-0.27.0-py3-none-win_arm64.whl", hash = "sha256:a6c129c311edf210a2b4f2f4acc557eff522628125f5f28ed27df19c16c07079", size = 22972710, upload-time = "2026-05-14T03:44:03.275Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yarl"
|
||||
version = "1.24.2"
|
||||
|
||||
Reference in New Issue
Block a user