r0mant1c commited on
Commit
90b2b0e
·
1 Parent(s): 87e13d2

Polish upload preview and deployment dependencies

Browse files
Files changed (4) hide show
  1. DEPLOYMENT_LOG.md +14 -0
  2. RUNBOOK.md +1 -1
  3. app.py +104 -25
  4. requirements.txt +1 -1
DEPLOYMENT_LOG.md CHANGED
@@ -26,6 +26,20 @@ CPU fallback after a Transformers failure is now opt-in with:
26
  AUTO_FALLBACK_TO_LLAMACPP=1
27
  ```
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  ## 2026-06-10 — Switch from Docker Space to Gradio ZeroGPU
30
 
31
  Decision: use **Gradio ZeroGPU** as the active Hugging Face Space architecture.
 
26
  AUTO_FALLBACK_TO_LLAMACPP=1
27
  ```
28
 
29
+ Follow-up fix: MiniCPM-V 4.6 declares `model_type: minicpmv4_6` and its official model card
30
+ requires `transformers[torch]>=5.7.0`. The Space was still pinned to `transformers==4.57.3`, which
31
+ caused the ZeroGPU worker to fail with:
32
+
33
+ ```text
34
+ Transformers does not recognize this architecture
35
+ ```
36
+
37
+ The runtime now pins:
38
+
39
+ ```text
40
+ transformers[torch]==5.7.0
41
+ ```
42
+
43
  ## 2026-06-10 — Switch from Docker Space to Gradio ZeroGPU
44
 
45
  Decision: use **Gradio ZeroGPU** as the active Hugging Face Space architecture.
RUNBOOK.md CHANGED
@@ -53,7 +53,7 @@ Install dependencies from `requirements.txt`, including:
53
  ```text
54
  spaces
55
  torch
56
- transformers
57
  llama-cpp-python
58
  ```
59
 
 
53
  ```text
54
  spaces
55
  torch
56
+ transformers[torch]==5.7.0
57
  llama-cpp-python
58
  ```
59
 
app.py CHANGED
@@ -135,6 +135,29 @@ def _display_status_label(status: str) -> str:
135
  return normalized.title() if normalized else "Unknown"
136
 
137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  def workflow_arrow_html(kind: str) -> str:
139
  kind = kind if kind in {"upload", "report"} else "upload"
140
  if kind == "upload":
@@ -190,19 +213,16 @@ def upload_state(uploaded_file: str | None) -> tuple[Any, Any]:
190
  workflow_phase_html("ready"),
191
  )
192
 
193
- filename = os.path.basename(uploaded_file)
194
  preview_data_url = _uploaded_file_preview_data_url(uploaded_file)
195
  return (
196
  gr.update(visible=False),
197
  gr.update(value="", visible=False),
198
- gr.update(visible=True, value=selected_document_html(filename, preview_data_url)),
199
  workflow_phase_html("processing"),
200
  )
201
 
202
 
203
- def selected_document_html(filename: str | None = None, preview_data_url: str | None = None) -> str:
204
- if not filename:
205
- filename = "Document ready"
206
  preview_markup = (
207
  f'<img class="bte-upload-preview-image" src="{escape(preview_data_url)}" alt="Uploaded document preview">'
208
  if preview_data_url
@@ -219,7 +239,6 @@ def selected_document_html(filename: str | None = None, preview_data_url: str |
219
  <div class="bte-selected-preview" aria-hidden="true">
220
  {preview_markup}
221
  <div class="bte-selected-preview-overlay"></div>
222
- <div class="bte-preview-watermark">{escape(filename)}</div>
223
  </div>
224
  </section>
225
  """
@@ -1021,7 +1040,7 @@ gradio-app,
1021
  margin: 0 auto 18px !important;
1022
  padding: 30px 28px 28px;
1023
  display: grid;
1024
- grid-template-columns: minmax(0, 1fr) minmax(360px, 0.46fr);
1025
  gap: 32px;
1026
  align-items: center;
1027
  border: 1px solid rgba(255, 255, 255, 0.42);
@@ -1053,6 +1072,69 @@ gradio-app,
1053
  min-width: 0;
1054
  }
1055
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1056
  .bte-title .bte-kicker,
1057
  .bte-title .bte-kicker *,
1058
  .bte-title h1,
@@ -1125,7 +1207,7 @@ gradio-app,
1125
  border: 1px solid var(--bte-line) !important;
1126
  border-radius: var(--bte-radius) !important;
1127
  padding: 18px !important;
1128
- background: var(--bte-card) !important;
1129
  box-shadow: var(--bte-shadow) !important;
1130
  overflow: hidden !important;
1131
  }
@@ -1137,7 +1219,7 @@ gradio-app,
1137
  border: 1px solid var(--bte-line) !important;
1138
  border-radius: var(--bte-radius) !important;
1139
  padding: 18px !important;
1140
- background: var(--bte-card) !important;
1141
  box-shadow: var(--bte-shadow) !important;
1142
  overflow: hidden !important;
1143
  }
@@ -1769,7 +1851,7 @@ gradio-app,
1769
  border: 1px solid #d8e2ee;
1770
  border-radius: 18px;
1771
  padding: 22px;
1772
- background: var(--bte-surface);
1773
  }
1774
 
1775
  .bte-selected-preview {
@@ -1777,7 +1859,7 @@ gradio-app,
1777
  min-height: 260px;
1778
  border-radius: 22px;
1779
  border: 1px solid rgba(216, 226, 238, 0.9);
1780
- background: linear-gradient(180deg, rgba(248, 249, 252, 0.95), rgba(255, 255, 255, 0.98));
1781
  overflow: hidden;
1782
  }
1783
 
@@ -1863,20 +1945,6 @@ gradio-app,
1863
  filter: blur(1.2px);
1864
  }
1865
 
1866
- .bte-preview-watermark {
1867
- position: absolute;
1868
- left: 34px;
1869
- right: 34px;
1870
- bottom: 28px;
1871
- color: rgba(17, 24, 39, 0.2);
1872
- font-size: 18px;
1873
- font-weight: 700;
1874
- letter-spacing: 0;
1875
- white-space: nowrap;
1876
- overflow: hidden;
1877
- text-overflow: ellipsis;
1878
- }
1879
-
1880
  .bte-selected-preview-overlay {
1881
  position: absolute;
1882
  inset: 0;
@@ -2968,6 +3036,15 @@ button.bte-action *,
2968
  gap: 18px;
2969
  }
2970
 
 
 
 
 
 
 
 
 
 
2971
  .bte-title h1,
2972
  .bte-report h2 {
2973
  font-size: 32px !important;
@@ -3177,6 +3254,8 @@ with gr.Blocks(title="Blood Test Explainer") as demo:
3177
  </div>
3178
  """
3179
  )
 
 
3180
 
3181
  workflow_phase = gr.HTML(
3182
  workflow_phase_html("ready"),
 
135
  return normalized.title() if normalized else "Unknown"
136
 
137
 
138
+ def hero_attribution_html() -> str:
139
+ items = [
140
+ ("Codex", "Build with Codex", "CDX", "aria-label=\"Codex logo\""),
141
+ ("OpenBMB", "Enabled with OpenBMB", "OB", "aria-label=\"OpenBMB logo\""),
142
+ ("Modal", "Finetuned with Modal", "M", "aria-label=\"Modal logo\""),
143
+ ("ACG", "Created by researchers at ACG", "ACG", "aria-label=\"ACG logo\""),
144
+ ]
145
+ badges = "\n".join(
146
+ f"""
147
+ <li class=\"bte-hero-badge bte-hero-badge--{escape(slug.lower())}\">
148
+ <span class=\"bte-hero-badge-mark\" {attrs}>{escape(mark)}</span>
149
+ <span class=\"bte-hero-badge-text\">{escape(label)}</span>
150
+ </li>
151
+ """
152
+ for slug, label, mark, attrs in items
153
+ )
154
+ return f"""
155
+ <ul class=\"bte-hero-attribution\" aria-label=\"Project attributions\">
156
+ {badges}
157
+ </ul>
158
+ """
159
+
160
+
161
  def workflow_arrow_html(kind: str) -> str:
162
  kind = kind if kind in {"upload", "report"} else "upload"
163
  if kind == "upload":
 
213
  workflow_phase_html("ready"),
214
  )
215
 
 
216
  preview_data_url = _uploaded_file_preview_data_url(uploaded_file)
217
  return (
218
  gr.update(visible=False),
219
  gr.update(value="", visible=False),
220
+ gr.update(visible=True, value=selected_document_html(preview_data_url=preview_data_url)),
221
  workflow_phase_html("processing"),
222
  )
223
 
224
 
225
+ def selected_document_html(preview_data_url: str | None = None) -> str:
 
 
226
  preview_markup = (
227
  f'<img class="bte-upload-preview-image" src="{escape(preview_data_url)}" alt="Uploaded document preview">'
228
  if preview_data_url
 
239
  <div class="bte-selected-preview" aria-hidden="true">
240
  {preview_markup}
241
  <div class="bte-selected-preview-overlay"></div>
 
242
  </div>
243
  </section>
244
  """
 
1040
  margin: 0 auto 18px !important;
1041
  padding: 30px 28px 28px;
1042
  display: grid;
1043
+ grid-template-columns: minmax(0, 1fr) minmax(280px, 360px);
1044
  gap: 32px;
1045
  align-items: center;
1046
  border: 1px solid rgba(255, 255, 255, 0.42);
 
1072
  min-width: 0;
1073
  }
1074
 
1075
+ .bte-title-attribution-wrap {
1076
+ min-width: 0;
1077
+ justify-self: end;
1078
+ }
1079
+
1080
+ .bte-hero-attribution {
1081
+ list-style: none;
1082
+ margin: 0;
1083
+ padding: 0;
1084
+ display: grid;
1085
+ gap: 10px;
1086
+ }
1087
+
1088
+ .bte-hero-badge {
1089
+ display: grid;
1090
+ grid-template-columns: 34px minmax(0, 1fr);
1091
+ gap: 12px;
1092
+ align-items: center;
1093
+ padding: 10px 12px;
1094
+ border-radius: 14px;
1095
+ background: rgba(255, 255, 255, 0.12);
1096
+ border: 1px solid rgba(255, 255, 255, 0.18);
1097
+ backdrop-filter: blur(6px);
1098
+ }
1099
+
1100
+ .bte-hero-badge-mark {
1101
+ width: 34px;
1102
+ height: 34px;
1103
+ border-radius: 11px;
1104
+ display: grid;
1105
+ place-items: center;
1106
+ color: #fff;
1107
+ font-size: 11px;
1108
+ font-weight: 800;
1109
+ letter-spacing: 0;
1110
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.26), rgba(255, 255, 255, 0.08));
1111
+ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
1112
+ }
1113
+
1114
+ .bte-hero-badge-text {
1115
+ color: #ffffff !important;
1116
+ -webkit-text-fill-color: #ffffff !important;
1117
+ font-size: 13px;
1118
+ line-height: 1.2;
1119
+ font-weight: 700;
1120
+ }
1121
+
1122
+ .bte-hero-badge--codex .bte-hero-badge-mark {
1123
+ background: linear-gradient(135deg, rgba(37, 99, 235, 0.95), rgba(18, 128, 92, 0.92));
1124
+ }
1125
+
1126
+ .bte-hero-badge--openbmb .bte-hero-badge-mark {
1127
+ background: linear-gradient(135deg, rgba(18, 128, 92, 0.95), rgba(37, 99, 235, 0.92));
1128
+ }
1129
+
1130
+ .bte-hero-badge--modal .bte-hero-badge-mark {
1131
+ background: linear-gradient(135deg, rgba(191, 52, 52, 0.95), rgba(37, 99, 235, 0.9));
1132
+ }
1133
+
1134
+ .bte-hero-badge--acg .bte-hero-badge-mark {
1135
+ background: linear-gradient(135deg, rgba(90, 99, 214, 0.95), rgba(18, 128, 92, 0.9));
1136
+ }
1137
+
1138
  .bte-title .bte-kicker,
1139
  .bte-title .bte-kicker *,
1140
  .bte-title h1,
 
1207
  border: 1px solid var(--bte-line) !important;
1208
  border-radius: var(--bte-radius) !important;
1209
  padding: 18px !important;
1210
+ background: var(--bte-page) !important;
1211
  box-shadow: var(--bte-shadow) !important;
1212
  overflow: hidden !important;
1213
  }
 
1219
  border: 1px solid var(--bte-line) !important;
1220
  border-radius: var(--bte-radius) !important;
1221
  padding: 18px !important;
1222
+ background: var(--bte-page) !important;
1223
  box-shadow: var(--bte-shadow) !important;
1224
  overflow: hidden !important;
1225
  }
 
1851
  border: 1px solid #d8e2ee;
1852
  border-radius: 18px;
1853
  padding: 22px;
1854
+ background: var(--bte-page);
1855
  }
1856
 
1857
  .bte-selected-preview {
 
1859
  min-height: 260px;
1860
  border-radius: 22px;
1861
  border: 1px solid rgba(216, 226, 238, 0.9);
1862
+ background: var(--bte-page);
1863
  overflow: hidden;
1864
  }
1865
 
 
1945
  filter: blur(1.2px);
1946
  }
1947
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1948
  .bte-selected-preview-overlay {
1949
  position: absolute;
1950
  inset: 0;
 
3036
  gap: 18px;
3037
  }
3038
 
3039
+ .bte-title-attribution-wrap {
3040
+ justify-self: start;
3041
+ width: 100%;
3042
+ }
3043
+
3044
+ .bte-hero-attribution {
3045
+ grid-template-columns: 1fr;
3046
+ }
3047
+
3048
  .bte-title h1,
3049
  .bte-report h2 {
3050
  font-size: 32px !important;
 
3254
  </div>
3255
  """
3256
  )
3257
+ with gr.Column(scale=0, min_width=300, elem_classes=["bte-title-attribution-wrap"]):
3258
+ gr.HTML(hero_attribution_html())
3259
 
3260
  workflow_phase = gr.HTML(
3261
  workflow_phase_html("ready"),
requirements.txt CHANGED
@@ -7,7 +7,7 @@ json-repair==0.60.1
7
  # ZeroGPU/CUDA path for EXTRACTOR_BACKEND=auto: the app uses the official OpenBMB
8
  # Transformers pipeline when ACCELERATOR is ZeroGPU, ZERO_GPU=TRUE, or CUDA is visible.
9
  torch==2.9.1 ; sys_platform == "linux" and platform_machine == "x86_64"
10
- transformers==4.57.3
11
  accelerate==1.12.0
12
  bitsandbytes==0.48.2 ; sys_platform == "linux" and platform_machine == "x86_64"
13
  torchvision==0.24.1 ; sys_platform == "linux" and platform_machine == "x86_64"
 
7
  # ZeroGPU/CUDA path for EXTRACTOR_BACKEND=auto: the app uses the official OpenBMB
8
  # Transformers pipeline when ACCELERATOR is ZeroGPU, ZERO_GPU=TRUE, or CUDA is visible.
9
  torch==2.9.1 ; sys_platform == "linux" and platform_machine == "x86_64"
10
+ transformers[torch]==5.7.0
11
  accelerate==1.12.0
12
  bitsandbytes==0.48.2 ; sys_platform == "linux" and platform_machine == "x86_64"
13
  torchvision==0.24.1 ; sys_platform == "linux" and platform_machine == "x86_64"