Skip to content

Commit 2ebc8a9

Browse files
committed
fix(Weights loader): Add debug output and expose Docker log file
1 parent 0c72c4a commit 2ebc8a9

File tree

10 files changed

+572
-540
lines changed

10 files changed

+572
-540
lines changed

.editorconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@ indent_size = 2
2020
[Makefile]
2121
indent_style = tab
2222
indent_size = 4
23+
24+
[*.py]
25+
indent_style = space
26+
indent_size = 4

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@ coverage
4242
tmp
4343
public/resized
4444
models
45+
weights.log

Makefile

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,31 @@
1+
login-check:
2+
huggingface-cli whoami
3+
14
login:
25
@echo "🔐 Logging in to Hugging Face CLI..."
36
huggingface-cli login
47
@echo "Verify account"
58
huggingface-cli whoami
69

710
load-weights:
11+
@echo "Part 1/3 Build docker image"
812
docker build \
913
--build-arg MODEL_REPO="$(MODEL_REPO)" \
1014
--build-arg FILENAMES="$(FILENAMES)" \
1115
-f apps/load-weights/Dockerfile \
1216
-t weights-loader .
13-
docker create --name extract-model weights-loader
17+
@echo "Part 2/3 Extracting weights from Hugging Face using cached credential"
18+
docker run --name extract-model \
19+
-v $$HOME/.cache/huggingface:/root/.cache/huggingface \
20+
-e MODEL_REPO="$(MODEL_REPO)" \
21+
-e FILENAMES="$(FILENAMES)" \
22+
weights-loader \
23+
sh -c 'python /dock/hugging-offline.py --repo-id "$$MODEL_REPO" --filenames "$$FILENAMES" > /dock/build.log 2>&1'
24+
@echo "Part 3/3 Copying weights to local directory and display log"
1425
docker cp extract-model:/dock/models/. ./models/
26+
docker cp extract-model:/dock/build.log ./weights.log || true
1527
docker rm extract-model
28+
cat ./weights.log || true
1629

1730
build-ai-api:
1831
docker build -f apps/api/Dockerfile -t ai-api .

apps/api/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ This project serves a high-accuracy image classification API using a **Vision Tr
3636
- **Aesthetic scoring** using a trained multilayer perceptron (MLP)
3737
- Deterministic evaluation
3838
- A custom regression MLP head trained on:
39-
- AVA dataset (aesthetics annotated)
39+
- [AVA dataset (aesthetics annotated)](https://github.com/microsoft/LMOps/blob/main/promptist/aesthetic/ava%2Blogos-l14-linearMSE.pth)
4040
- Logos subset (for composition)
4141
- [Code sample](https://github.com/christophschuhmann/improved-aesthetic-predictor/tree/main)

apps/api/main.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ async def classify_endpoint(req: Request):
3838
@main_py_app.post("/scores")
3939
async def score_endpoint(req: Request):
4040
try:
41-
score = await score_aesthetic(req)
42-
return {"aesthetic_score": round(score, 3)}
41+
return {"aesthetic_score": await score_aesthetic(req)}
4342
except Exception as e:
4443
return error_response(e)

apps/load-weights/Dockerfile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ ARG FILENAMES
55

66
ENV MODEL_REPO="${MODEL_REPO}"
77
ENV FILENAMES="${FILENAMES}"
8-
# Ensures Python output shows up immediately
9-
ENV PYTHONUNBUFFERED=1
108

119
WORKDIR /dock
1210

@@ -17,4 +15,3 @@ COPY apps/load-weights/hugging-offline.py /dock/hugging-offline.py
1715

1816
RUN echo "MODEL_REPO: '$MODEL_REPO'"
1917
RUN echo "FILENAMES: '$FILENAMES'"
20-
RUN python /dock/hugging-offline.py --repo-id "$MODEL_REPO" --filenames $(echo $FILENAMES)

apps/load-weights/README.md

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,12 @@ Hugging Face timm https://huggingface.co/timm/convnext_large_mlp.laion2b_ft_augr
55

66

77
## Image classifier
8-
1. Build container `make build-load-weights MODEL_REPO=timm/eva02_large_patch14_clip_336.merged2b_ft_inat21 FILENAMES="pytorch_model.bin"`
9-
1. Run container
10-
```
11-
docker run --rm \
12-
-v "$HOME/.cache/huggingface":/root/.cache/huggingface \
13-
weights-loader
14-
```
15-
16-
Then copy from the Hugging Face cache to the repo
17-
- `mkdir -p models/timm_eva02_large_patch14_clip_336.merged2b_ft_inat21`
18-
- ```
19-
cp $HOME/.cache/huggingface/hub/models--timm--eva02_large_patch14_clip_336.merged2b_ft_inat21/snapshots/*/pytorch_model.bin \
20-
models/timm_eva02_large_patch14_clip_336.merged2b_ft_inat21/
21-
```
8+
9+
`make load-weights MODEL_REPO=timm/eva02_large_patch14_clip_336.merged2b_ft_inat21 FILENAMES="pytorch_model.bin"`
10+
11+
## Aesthetic Scorer
12+
13+
`make load-weights MODEL_REPO=apple/DFN5B-CLIP-ViT-H-14-378 FILENAMES="open_clip_pytorch_model.bin open_clip_config.json"`
14+
15+
16+
`make load-weights MODEL_REPO=CrowsonKB/simulacra-aesthetic-model FILENAMES="simulacra_aesthetic_model.pth"`

apps/load-weights/hugging-offline.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,27 @@
77
import os
88
import sys
99
import logging
10-
import traceback
10+
import subprocess
1111

1212
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, force=True)
1313
logger = logging.getLogger()
1414
logger.setLevel(logging.DEBUG)
1515

16+
def log_huggingface_whoami():
17+
logger.info("🔑 Checking Hugging Face authentication with 'huggingface-cli whoami'...")
18+
try:
19+
result = subprocess.run(
20+
["huggingface-cli", "whoami"],
21+
capture_output=True,
22+
text=True,
23+
check=True
24+
)
25+
logger.info(f"Hugging Face user: {result.stdout.strip()}")
26+
except Exception as e:
27+
logger.error(f"❌ Unable to verify Hugging Face authentication: {e}")
28+
1629
def download_weights(repo_id: str, filenames: list[str]):
30+
log_huggingface_whoami()
1731
# Create destination path
1832
dest_dir = os.path.join("models", repo_id.replace("/", "_"))
1933
os.makedirs(dest_dir, exist_ok=True)
@@ -22,28 +36,37 @@ def download_weights(repo_id: str, filenames: list[str]):
2236
logger.info(f"📥 Downloading {filename} from {repo_id} on Hugging Face Hub...")
2337
try:
2438
path = hf_hub_download(repo_id=repo_id, filename=filename)
25-
2639
# Move and rename
2740
dest_path = os.path.join(dest_dir, filename)
2841
shutil.copy(path, dest_path)
42+
logger.info(f"✅ Saved {filename} to {dest_path}")
2943
except (RepositoryNotFoundError, HfHubHTTPError) as e:
3044
logger.error(f"❌ Failed to fetch '{filename}' from '{repo_id}': {e}")
3145
continue
3246

33-
logger.info(f"✅ All saved to: {dest_dir}")
47+
# Verification step
48+
missing = []
49+
for filename in filenames:
50+
dest_path = os.path.join(dest_dir, filename)
51+
if not os.path.isfile(dest_path):
52+
missing.append(filename)
53+
if missing:
54+
logger.error(f"❌ The following files are missing after download: {missing}")
55+
else:
56+
logger.info(f"✅ All expected files present in: {dest_dir}")
3457

3558
if __name__ == "__main__":
36-
parser = argparse.ArgumentParser(description="Download Hugging Face model weights")
37-
parser.add_argument(
38-
"--repo-id",
39-
required=True,
40-
help="Hugging Face repository ID (e.g., openai/clip-vit-base-patch32)"
41-
)
42-
parser.add_argument(
43-
"--filenames",
44-
nargs="+",
45-
default=["pytorch_model.bin", "config.json"],
46-
help="List of filenames to download (space-separated)"
47-
)
48-
args = parser.parse_args()
49-
download_weights(args.repo_id, args.filenames)
59+
parser = argparse.ArgumentParser(description="Download Hugging Face model weights")
60+
parser.add_argument(
61+
"--repo-id",
62+
required=True,
63+
help="Hugging Face repository ID (e.g., openai/clip-vit-base-patch32)"
64+
)
65+
parser.add_argument(
66+
"--filenames",
67+
nargs="+",
68+
default=["pytorch_model.bin", "config.json"],
69+
help="List of filenames to download (space-separated)"
70+
)
71+
args = parser.parse_args()
72+
download_weights(args.repo_id, args.filenames)

0 commit comments

Comments
 (0)