jhonier23 commited on
Commit
09bd849
·
1 Parent(s): ea19e8c
Files changed (2) hide show
  1. README.md +7 -6
  2. app.py +73 -10
README.md CHANGED
@@ -35,12 +35,13 @@ remain on CPU Basic: when a user starts training, AutoTrain SpaceRunner creates
35
  temporary L40S training Space under that user's account and publishes the finished
36
  LoRA to their model repository.
37
 
38
- Captioning defaults to `lienthealien/mage-vl-demo`, which uses the Apache-2.0
39
- `microsoft/Mage-VL` model. If that Space is private, add
40
- `MAGE_VL_TOKEN` as a secret in this Space's settings. It only needs permission to
41
- call the Mage-VL Space. `MAGE_VL_SPACE_ID` and `MAGE_VL_API_NAME` can be set as
42
- Space variables if you use a different duplicate or endpoint. Uploaded images are
43
- sent to that configured Space for captioning, so use a Space you trust.
 
44
 
45
  The user must:
46
 
 
35
  temporary L40S training Space under that user's account and publishes the finished
36
  LoRA to their model repository.
37
 
38
+ Captioning defaults to the public `microsoft/mage-vl-demo`, which uses the
39
+ Apache-2.0 `microsoft/Mage-VL` model. No repository token is required for reading
40
+ its API. `MAGE_VL_SPACE_ID` and `MAGE_VL_API_NAME` can be set as Space variables
41
+ if you use a different duplicate or endpoint. `MAGE_VL_BASE_URL` can override the
42
+ derived `https://OWNER-SPACE.hf.space` URL. If that override is private, add a token
43
+ with access to it as the `MAGE_VL_TOKEN` Space secret. Uploaded images are sent to
44
+ the configured captioning Space, so use a Space you trust.
45
 
46
  The user must:
47
 
app.py CHANGED
@@ -1,10 +1,11 @@
1
  import gradio as gr
2
  import subprocess
3
  import os
 
4
  is_spaces = True if os.environ.get('SPACE_ID') else False
5
  if is_spaces:
6
  import spaces
7
- from gradio_client import Client, handle_file, utils as gradio_client_utils
8
  from huggingface_hub import snapshot_download, HfApi
9
  import uuid
10
  import shutil
@@ -28,8 +29,12 @@ TRAINING_SCRIPT = Path("train_dreambooth_lora_sdxl_advanced.py")
28
  training_script_url = f"https://raw.githubusercontent.com/huggingface/diffusers/{DIFFUSERS_COMMIT}/examples/advanced_diffusion_training/{TRAINING_SCRIPT.name}"
29
  orchestrator_script_url = "https://huggingface.co/datasets/multimodalart/lora-ease-helper/raw/main/script.py"
30
 
31
- MAGE_VL_SPACE_ID = os.environ.get("MAGE_VL_SPACE_ID", "lienthealien/mage-vl-demo")
32
  MAGE_VL_API_NAME = os.environ.get("MAGE_VL_API_NAME", "/ask_image")
 
 
 
 
33
  mage_vl_client = None
34
  caption_cache = {}
35
 
@@ -76,12 +81,75 @@ def get_face_prior_dataset():
76
  return dataset_path
77
 
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  def get_captioner():
80
  """Connect to the dedicated Mage-VL Space without loading a VLM here."""
81
  global mage_vl_client
82
  if mage_vl_client is None:
83
- token = os.environ.get("MAGE_VL_TOKEN") or os.environ.get("HF_TOKEN")
84
- mage_vl_client = Client(MAGE_VL_SPACE_ID, hf_token=token, verbose=False)
85
  return mage_vl_client
86
 
87
 
@@ -91,12 +159,7 @@ def caption_with_mage(client, image, instruction):
91
  if cache_key in caption_cache:
92
  return caption_cache[cache_key]
93
 
94
- result = client.predict(
95
- handle_file(image),
96
- instruction,
97
- 160,
98
- api_name=MAGE_VL_API_NAME,
99
- )
100
  caption = result[0] if isinstance(result, (list, tuple)) else result
101
  caption = str(caption).strip().rstrip(" .,")
102
  caption_cache[cache_key] = caption
 
1
  import gradio as gr
2
  import subprocess
3
  import os
4
+ import requests
5
  is_spaces = True if os.environ.get('SPACE_ID') else False
6
  if is_spaces:
7
  import spaces
8
+ from gradio_client import utils as gradio_client_utils
9
  from huggingface_hub import snapshot_download, HfApi
10
  import uuid
11
  import shutil
 
29
  training_script_url = f"https://raw.githubusercontent.com/huggingface/diffusers/{DIFFUSERS_COMMIT}/examples/advanced_diffusion_training/{TRAINING_SCRIPT.name}"
30
  orchestrator_script_url = "https://huggingface.co/datasets/multimodalart/lora-ease-helper/raw/main/script.py"
31
 
32
+ MAGE_VL_SPACE_ID = os.environ.get("MAGE_VL_SPACE_ID", "microsoft/mage-vl-demo")
33
  MAGE_VL_API_NAME = os.environ.get("MAGE_VL_API_NAME", "/ask_image")
34
+ MAGE_VL_BASE_URL = os.environ.get(
35
+ "MAGE_VL_BASE_URL",
36
+ f"https://{MAGE_VL_SPACE_ID.replace('/', '-').lower()}.hf.space",
37
+ ).rstrip("/")
38
  mage_vl_client = None
39
  caption_cache = {}
40
 
 
81
  return dataset_path
82
 
83
 
84
+ class MageVLClient:
85
+ """Minimal Gradio HTTP client, independent of the local Gradio version."""
86
+
87
+ def __init__(self, base_url, api_name, token=None):
88
+ self.base_url = base_url
89
+ self.api_name = api_name.strip("/")
90
+ self.session = requests.Session()
91
+ if token:
92
+ self.session.headers.update({"Authorization": f"Bearer {token}"})
93
+
94
+ response = self.session.get(f"{self.base_url}/gradio_api/info", timeout=30)
95
+ response.raise_for_status()
96
+ endpoints = response.json().get("named_endpoints", {})
97
+ if f"/{self.api_name}" not in endpoints:
98
+ raise RuntimeError(
99
+ f"Mage-VL endpoint '/{self.api_name}' was not found at {self.base_url}."
100
+ )
101
+
102
+ def predict(self, image, instruction, max_new_tokens):
103
+ with open(image, "rb") as image_file:
104
+ upload = self.session.post(
105
+ f"{self.base_url}/gradio_api/upload",
106
+ files={"files": (os.path.basename(image), image_file)},
107
+ timeout=60,
108
+ )
109
+ upload.raise_for_status()
110
+ uploaded_path = upload.json()[0]
111
+
112
+ payload = {
113
+ "data": [
114
+ {
115
+ "path": uploaded_path,
116
+ "orig_name": os.path.basename(image),
117
+ "meta": {"_type": "gradio.FileData"},
118
+ },
119
+ instruction,
120
+ int(max_new_tokens),
121
+ ]
122
+ }
123
+ start = self.session.post(
124
+ f"{self.base_url}/gradio_api/call/{self.api_name}",
125
+ json=payload,
126
+ timeout=30,
127
+ )
128
+ start.raise_for_status()
129
+ event_id = start.json()["event_id"]
130
+
131
+ result = self.session.get(
132
+ f"{self.base_url}/gradio_api/call/{self.api_name}/{event_id}",
133
+ timeout=180,
134
+ )
135
+ result.raise_for_status()
136
+ event = None
137
+ for line in result.text.splitlines():
138
+ if line.startswith("event:"):
139
+ event = line.partition(":")[2].strip()
140
+ elif line.startswith("data:") and event == "complete":
141
+ return json.loads(line.partition(":")[2].strip())
142
+ elif line.startswith("data:") and event == "error":
143
+ raise RuntimeError(line.partition(":")[2].strip())
144
+ raise RuntimeError(f"Mage-VL returned no completed result: {result.text[:500]}")
145
+
146
+
147
  def get_captioner():
148
  """Connect to the dedicated Mage-VL Space without loading a VLM here."""
149
  global mage_vl_client
150
  if mage_vl_client is None:
151
+ token = os.environ.get("MAGE_VL_TOKEN")
152
+ mage_vl_client = MageVLClient(MAGE_VL_BASE_URL, MAGE_VL_API_NAME, token)
153
  return mage_vl_client
154
 
155
 
 
159
  if cache_key in caption_cache:
160
  return caption_cache[cache_key]
161
 
162
+ result = client.predict(image, instruction, 160)
 
 
 
 
 
163
  caption = result[0] if isinstance(result, (list, tuple)) else result
164
  caption = str(caption).strip().rstrip(" .,")
165
  caption_cache[cache_key] = caption