Spaces:
Running
Running
Adrian Gabriel commited on
Commit ·
689b46a
1
Parent(s): 0629791
latest changs
Browse files- Dockerfile +8 -10
- instrumentation.py +14 -2
- requirements.txt +4 -0
- static/index.html +54 -5
Dockerfile
CHANGED
|
@@ -1,25 +1,23 @@
|
|
| 1 |
-
# Use
|
| 2 |
FROM python:3.9-slim
|
| 3 |
|
| 4 |
-
# Set
|
| 5 |
WORKDIR /code
|
| 6 |
|
| 7 |
-
# 1.
|
|
|
|
| 8 |
COPY ./requirements.txt /code/requirements.txt
|
| 9 |
-
|
| 10 |
-
# 2. Install dependencies
|
| 11 |
-
# We use --no-cache-dir to keep the image small
|
| 12 |
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
| 13 |
|
| 14 |
-
#
|
| 15 |
COPY . /code
|
| 16 |
|
| 17 |
-
#
|
| 18 |
RUN useradd -m -u 1000 user
|
| 19 |
USER user
|
| 20 |
ENV HOME=/home/user \
|
| 21 |
PATH=/home/user/.local/bin:$PATH
|
| 22 |
|
| 23 |
-
#
|
| 24 |
-
# IMPORTANT: Hugging Face
|
| 25 |
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
|
|
|
| 1 |
+
# Use Python 3.9
|
| 2 |
FROM python:3.9-slim
|
| 3 |
|
| 4 |
+
# Set working directory
|
| 5 |
WORKDIR /code
|
| 6 |
|
| 7 |
+
# 1. Install dependencies
|
| 8 |
+
# We copy requirements first to cache them effectively
|
| 9 |
COPY ./requirements.txt /code/requirements.txt
|
|
|
|
|
|
|
|
|
|
| 10 |
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
| 11 |
|
| 12 |
+
# 2. Copy the rest of the application
|
| 13 |
COPY . /code
|
| 14 |
|
| 15 |
+
# 3. Security: Create a non-root user (Required for HF Spaces)
|
| 16 |
RUN useradd -m -u 1000 user
|
| 17 |
USER user
|
| 18 |
ENV HOME=/home/user \
|
| 19 |
PATH=/home/user/.local/bin:$PATH
|
| 20 |
|
| 21 |
+
# 4. Run the application
|
| 22 |
+
# IMPORTANT: Hugging Face listens on port 7860 by default!
|
| 23 |
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
instrumentation.py
CHANGED
|
@@ -123,9 +123,21 @@ class Instrumentor:
|
|
| 123 |
# Get the layer name
|
| 124 |
layer_name = instance.__class__.__name__
|
| 125 |
|
| 126 |
-
#
|
|
|
|
| 127 |
meta = {'layer_type': layer_name}
|
| 128 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
|
| 130 |
return result
|
| 131 |
|
|
|
|
| 123 |
# Get the layer name
|
| 124 |
layer_name = instance.__class__.__name__
|
| 125 |
|
| 126 |
+
# Build inputs list - for Linear, include weight and bias
|
| 127 |
+
inputs = [x]
|
| 128 |
meta = {'layer_type': layer_name}
|
| 129 |
+
|
| 130 |
+
# For Linear layers, include weight and bias for visualization
|
| 131 |
+
if layer_name == 'Linear':
|
| 132 |
+
if hasattr(instance, 'weight'):
|
| 133 |
+
inputs.append(instance.weight)
|
| 134 |
+
meta['has_weight'] = True
|
| 135 |
+
if hasattr(instance, 'bias') and instance.bias is not None:
|
| 136 |
+
inputs.append(instance.bias)
|
| 137 |
+
meta['has_bias'] = True
|
| 138 |
+
|
| 139 |
+
# Emit op event for the layer
|
| 140 |
+
instrumentor.tracer.op(layer_name.lower(), inputs, result, meta)
|
| 141 |
|
| 142 |
return result
|
| 143 |
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
fastapi
|
| 2 |
+
uvicorn
|
| 3 |
+
numpy
|
| 4 |
+
# Add any other libraries you import in your python code
|
static/index.html
CHANGED
|
@@ -204,16 +204,17 @@
|
|
| 204 |
min-width: 50px;
|
| 205 |
}
|
| 206 |
|
| 207 |
-
.layout-grid { gap:
|
| 208 |
.layout-binary {
|
| 209 |
grid-template-columns: auto auto;
|
| 210 |
grid-template-rows: auto auto;
|
| 211 |
-
gap:
|
| 212 |
}
|
| 213 |
.layout-unary { grid-template-columns: auto; }
|
| 214 |
-
|
| 215 |
-
.pos-
|
| 216 |
-
.pos-
|
|
|
|
| 217 |
|
| 218 |
/* Element-wise operation layout: inputs side by side, result below left */
|
| 219 |
.layout-elementwise {
|
|
@@ -234,6 +235,18 @@
|
|
| 234 |
padding: 0 8px;
|
| 235 |
user-select: none;
|
| 236 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 237 |
|
| 238 |
/* TOOLBAR */
|
| 239 |
#toolbar {
|
|
@@ -1352,6 +1365,7 @@ box("Loss Computation", [y_pred, target_probs, loss], "6")
|
|
| 1352 |
const isElementwise = ['add', 'sub', 'mul', 'div'].includes(type) && inputs.length >= 2;
|
| 1353 |
const isMatmul = type === 'matmul' && inputs.length >= 2;
|
| 1354 |
const isLoss = ['mseloss', 'crossentropyloss', 'bceloss'].includes(type) && inputs.length >= 2;
|
|
|
|
| 1355 |
|
| 1356 |
// Determine output orientation for reduction operations
|
| 1357 |
let outputOrientation = 'auto';
|
|
@@ -1434,6 +1448,41 @@ box("Loss Computation", [y_pred, target_probs, loss], "6")
|
|
| 1434 |
return;
|
| 1435 |
}
|
| 1436 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1437 |
if (isMatmul) {
|
| 1438 |
// Matrix multiplication: keep grid layout for proper alignment
|
| 1439 |
const grid = document.createElement('div');
|
|
|
|
| 204 |
min-width: 50px;
|
| 205 |
}
|
| 206 |
|
| 207 |
+
.layout-grid { gap: 8px; } /* display: inline-grid set above */
|
| 208 |
.layout-binary {
|
| 209 |
grid-template-columns: auto auto;
|
| 210 |
grid-template-rows: auto auto;
|
| 211 |
+
gap: 8px;
|
| 212 |
}
|
| 213 |
.layout-unary { grid-template-columns: auto; }
|
| 214 |
+
/* Matmul layout: a on left, b on top-right, result on bottom-right */
|
| 215 |
+
.pos-left { grid-row: 2; grid-column: 1; align-self: start; }
|
| 216 |
+
.pos-top { grid-row: 1; grid-column: 2; align-self: end; }
|
| 217 |
+
.pos-result { grid-row: 2; grid-column: 2; align-self: start; }
|
| 218 |
|
| 219 |
/* Element-wise operation layout: inputs side by side, result below left */
|
| 220 |
.layout-elementwise {
|
|
|
|
| 235 |
padding: 0 8px;
|
| 236 |
user-select: none;
|
| 237 |
}
|
| 238 |
+
|
| 239 |
+
/* Linear layer layout: matmul-style with X on top, W on left, result at intersection */
|
| 240 |
+
.layout-linear {
|
| 241 |
+
display: inline-grid;
|
| 242 |
+
grid-template-columns: auto auto;
|
| 243 |
+
grid-template-rows: auto auto;
|
| 244 |
+
gap: 8px;
|
| 245 |
+
}
|
| 246 |
+
.linear-empty { grid-row: 1; grid-column: 1; } /* Empty top-left cell */
|
| 247 |
+
.linear-input { grid-row: 1; grid-column: 2; align-self: end; } /* X on top, aligned to bottom */
|
| 248 |
+
.linear-weight { grid-row: 2; grid-column: 1; align-self: start; } /* W on left, aligned to top */
|
| 249 |
+
.linear-output { grid-row: 2; grid-column: 2; align-self: start; } /* Result aligned to top with W */
|
| 250 |
|
| 251 |
/* TOOLBAR */
|
| 252 |
#toolbar {
|
|
|
|
| 1365 |
const isElementwise = ['add', 'sub', 'mul', 'div'].includes(type) && inputs.length >= 2;
|
| 1366 |
const isMatmul = type === 'matmul' && inputs.length >= 2;
|
| 1367 |
const isLoss = ['mseloss', 'crossentropyloss', 'bceloss'].includes(type) && inputs.length >= 2;
|
| 1368 |
+
const isLinear = type === 'linear' && inputs.length >= 2 && meta?.has_weight;
|
| 1369 |
|
| 1370 |
// Determine output orientation for reduction operations
|
| 1371 |
let outputOrientation = 'auto';
|
|
|
|
| 1448 |
return;
|
| 1449 |
}
|
| 1450 |
|
| 1451 |
+
if (isLinear) {
|
| 1452 |
+
// Linear layer: show as matmul with bias trick
|
| 1453 |
+
// inputs[0] = x, inputs[1] = weight, inputs[2] = bias (optional)
|
| 1454 |
+
const x = inputs[0];
|
| 1455 |
+
const weight = inputs[1];
|
| 1456 |
+
const bias = inputs.length > 2 ? inputs[2] : null;
|
| 1457 |
+
|
| 1458 |
+
const wrapper = document.createElement('div');
|
| 1459 |
+
wrapper.className = 'layout-linear';
|
| 1460 |
+
|
| 1461 |
+
// Empty cell for top-left (matmul alignment)
|
| 1462 |
+
const emptyCell = document.createElement('div');
|
| 1463 |
+
emptyCell.className = 'linear-empty';
|
| 1464 |
+
wrapper.appendChild(emptyCell);
|
| 1465 |
+
|
| 1466 |
+
// Input X (top-right position, like matmul)
|
| 1467 |
+
const inputCard = createMatrixCard(x.name || 'x', x);
|
| 1468 |
+
inputCard.classList.add('linear-input');
|
| 1469 |
+
wrapper.appendChild(inputCard);
|
| 1470 |
+
|
| 1471 |
+
// Weight matrix (left position)
|
| 1472 |
+
let weightLabel = weight.name || 'W';
|
| 1473 |
+
const weightCard = createMatrixCard(weightLabel, weight);
|
| 1474 |
+
weightCard.classList.add('linear-weight');
|
| 1475 |
+
wrapper.appendChild(weightCard);
|
| 1476 |
+
|
| 1477 |
+
// Output (bottom-right, result of x @ W + b)
|
| 1478 |
+
const outputCard = createMatrixCard(output.name || 'y', output);
|
| 1479 |
+
outputCard.classList.add('linear-output');
|
| 1480 |
+
wrapper.appendChild(outputCard);
|
| 1481 |
+
|
| 1482 |
+
container.appendChild(wrapper);
|
| 1483 |
+
return;
|
| 1484 |
+
}
|
| 1485 |
+
|
| 1486 |
if (isMatmul) {
|
| 1487 |
// Matrix multiplication: keep grid layout for proper alignment
|
| 1488 |
const grid = document.createElement('div');
|