Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 38 additions & 14 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -1,60 +1,84 @@
name: Deploy TabICL website to GitHub Pages
name: Validate and deploy tutorial website

# Publishes materials/website as the repository's GitHub Pages site after
# building the standalone Svelte explorer.

on:
pull_request:
paths:
- "materials/website/**"
- "materials/tabicl-explainer/**"
- "tests/**"
- ".github/workflows/pages.yml"
push:
branches: [main]
paths:
- "materials/website/**"
- "materials/tabicl-explainer/**"
- "tests/**"
- ".github/workflows/pages.yml"
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

# Allow one concurrent deployment; don't cancel an in-progress publish.
concurrency:
group: pages
group: pages-${{ github.event.pull_request.number || 'publish' }}
cancel-in-progress: false

jobs:
deploy:
validate:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Configure Pages
uses: actions/configure-pages@v5

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
cache-dependency-path: materials/tabicl-explainer/package-lock.json

- name: Install explorer dependencies
working-directory: materials/tabicl-explainer
run: npm ci

- name: Check explorer types
working-directory: materials/tabicl-explainer
run: npm run check

- name: Test browser runtime
run: node --test tests/*.test.mjs

- name: Build TabICL explorer
working-directory: materials/tabicl-explainer
run: |
npm ci
npm run build
run: npm run build

- name: Upload website artifact
if: github.event_name != 'pull_request'
uses: actions/upload-pages-artifact@v3
with:
# Upload only the site folder so it becomes the Pages root;
# all asset paths in index.html are relative to this dir.
path: materials/website

deploy:
if: github.event_name != 'pull_request'
needs: validate
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Configure Pages
uses: actions/configure-pages@v5

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
23 changes: 22 additions & 1 deletion materials/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,23 @@ or Apple MPS on supported local hardware, with CPU as the fallback.

### Local or CI

On macOS, XGBoost also needs the OpenMP runtime:

```bash
brew install libomp
```

Use Python and OpenMP for the same processor architecture. On Apple Silicon,
use native `arm64` Python and Homebrew.

Use Python 3.11 in a fresh virtual environment:

```bash
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install --require-hashes -r requirements-lock.txt
jupyter lab notebooks/01_tabicl_primer.ipynb
jupyter nbconvert notebooks/01_tabicl_primer.ipynb \
--to html --execute --ExecutePreprocessor.timeout=2400
```

`requirements.txt` lists the direct dependencies; `requirements-lock.txt`
Expand All @@ -48,6 +58,17 @@ notebook verifies its immutable Hugging Face revision and checkpoint checksum
before model loading. An internet connection is needed for package, dataset,
and checkpoint downloads.

Open `notebooks/01_tabicl_primer.html` to inspect the executed notebook.
The locked environment includes `nbconvert` and the Python kernel. To edit the
notebook in JupyterLab, install the optional editor separately:

```bash
python -m pip install jupyterlab
jupyter lab notebooks/01_tabicl_primer.ipynb
```

JupyterLab is not part of the locked execution environment.

## Source and attribution

- Public tutorial: <https://affirm.github.io/tabular-foundation-models-tutorial/>
Expand Down
77 changes: 9 additions & 68 deletions materials/tabicl-explainer/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions materials/tabicl-explainer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@sveltejs/kit": "^2.53.3",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/d3": "^7.4.3",
"@types/node": "^20.19.43",
"autoprefixer": "^10.4.16",
"d3": "^7.9.0",
"postcss": "^8.4.33",
Expand Down
34 changes: 34 additions & 0 deletions materials/website/js/playground-worker-state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export function recoverWorkerError(state, message) {
switch (message.requestType) {
case "inspect":
case "predict":
if (message.tag !== state.queryTag) return false;
state.qInFlight = false;
state.qProba = null;
state.qClass = null;
state.selectedView = null;
state.selectedViewProbability = null;
state.attention = null;
state.attentionBlock = null;
state.attentionHeads = null;
break;
case "prepare":
if (message.tag !== state.prepTag) return false;
state.prepared = false;
state.qInFlight = false;
state.qQueued = false;
break;
case "grid":
if (message.tag !== state.gridTag) return false;
state.gridBusy = false;
state.grid = null;
state.surface = null;
break;
case "load":
state.loading = false;
break;
default:
return false;
}
return true;
}
8 changes: 7 additions & 1 deletion materials/website/js/playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Pure vanilla, no build step.
*/
import { predictKnn } from "./knn.js";
import { recoverWorkerError } from "./playground-worker-state.js";
import {
classIndexFromProbability,
contourSegments2d,
Expand Down Expand Up @@ -745,9 +746,14 @@ function ensureWorker() {
updateModelUI();
draw();
} else if (m.type === "error") {
state.loading = false; state.gridBusy = false; updateModelUI();
if (!recoverWorkerError(state, m)) return;
updateModelUI(); updateReadout(); updateCompanion(); draw();
if (state.model === "tfm") setStatus("error: " + m.message);
console.error(m.message);
if ((m.requestType === "inspect" || m.requestType === "predict") && state.qQueued) {
state.qQueued = false;
requestQuery();
}
}
};
}
Expand Down
Loading
Loading