File size: 4,549 Bytes
89342ca
5fb57bc
 
 
 
 
 
89342ca
5fb57bc
 
 
 
 
 
 
 
 
 
 
c761cde
5fb57bc
 
 
 
 
c761cde
 
 
 
 
 
 
 
 
 
 
 
 
5fb57bc
 
 
d7aedb1
 
 
 
 
 
 
 
 
 
 
 
5fb57bc
 
c761cde
 
 
 
d7aedb1
 
5fb57bc
 
 
c761cde
814f7d2
5fb57bc
662f7ea
 
5fb57bc
c761cde
89342ca
c761cde
5fb57bc
 
814f7d2
 
 
 
 
 
 
 
89342ca
 
 
 
5fb57bc
662f7ea
 
 
 
 
 
 
 
 
5fb57bc
89342ca
5fb57bc
89342ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
814f7d2
 
 
89342ca
 
5fb57bc
 
89342ca
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"""Public Gradio API for private-model PFF-PK inference."""

from __future__ import annotations

import os
from pathlib import Path

import gradio as gr
from huggingface_hub import hf_hub_download

ROOT = Path(__file__).resolve().parent
MODEL_REPO_ID = os.environ.get("MODEL_REPO_ID", "").strip()
MODEL_REVISION = os.environ.get("MODEL_REVISION", "").strip()
if not MODEL_REPO_ID or not MODEL_REVISION:
    raise RuntimeError("MODEL_REPO_ID and MODEL_REVISION must be configured")

token = os.environ.get("HF_TOKEN") or True
checkpoint = hf_hub_download(
    repo_id=MODEL_REPO_ID,
    filename="models/pythia-dose/model.ckpt",
    revision=MODEL_REVISION,
    token=token,
)
config = hf_hub_download(
    repo_id=MODEL_REPO_ID,
    filename="models/pythia-dose/config.yaml",
    revision=MODEL_REVISION,
    token=token,
)
pythia_checkpoint = hf_hub_download(
    repo_id=MODEL_REPO_ID,
    filename="models/pythia/model.ckpt",
    revision=MODEL_REVISION,
    token=token,
)
pythia_config = hf_hub_download(
    repo_id=MODEL_REPO_ID,
    filename="models/pythia/config.yaml",
    revision=MODEL_REVISION,
    token=token,
)
covariates_checkpoint = hf_hub_download(
    repo_id=MODEL_REPO_ID,
    filename="models/pythia-covariates/model.ckpt",
    revision=MODEL_REVISION,
    token=token,
)
covariates_config = hf_hub_download(
    repo_id=MODEL_REPO_ID,
    filename="models/pythia-covariates/config.yaml",
    revision=MODEL_REVISION,
    token=token,
)

os.environ["PFF_REPO"] = str(ROOT)
os.environ["PFF_DOSE_CHECKPOINT"] = checkpoint
os.environ["PFF_DOSE_CONFIG"] = config
os.environ["PFF_PYTHIA_CHECKPOINT"] = pythia_checkpoint
os.environ["PFF_PYTHIA_CONFIG"] = pythia_config
os.environ["PFF_COVARIATES_CHECKPOINT"] = covariates_checkpoint
os.environ["PFF_COVARIATES_CONFIG"] = covariates_config
os.environ.setdefault("PFF_CACHE_ROOT", "/tmp/pff-inference-cache")
os.environ.setdefault("PFF_CPU_THREADS", "2")

from services.inference.pff_service import cached_inference, service_status  # noqa: E402
from services.inference.synthetic_service import synthetic_request  # noqa: E402

PUBLIC_SOLVER = {"method": "heun", "steps": 8}


def health() -> dict:
    """Return only non-sensitive deployment metadata."""
    return service_status()


def synthetic(payload: dict) -> dict:
    """Generate with the bundled, provenance-recorded synthetic_priors package."""
    try:
        return synthetic_request(payload)
    except Exception as error:
        raise gr.Error(str(error)) from error


def inference(payload: dict) -> dict:
    """Generate a PK cohort from a validated dashboard request."""
    if not isinstance(payload, dict):
        raise gr.Error("The inference request must be a JSON object")
    try:
        solver = payload.get("solver") or PUBLIC_SOLVER
        if not isinstance(solver, dict):
            raise ValueError("The public demo uses fixed Heun integration with 8 steps")
        if (
            str(solver.get("method", "")).lower() != PUBLIC_SOLVER["method"]
            or float(solver.get("steps", 0)) != PUBLIC_SOLVER["steps"]
        ):
            raise ValueError("The public demo uses fixed Heun integration with 8 steps")
        return cached_inference({**payload, "solver": PUBLIC_SOLVER.copy()})
    except (ValueError, KeyError, TypeError, FileNotFoundError) as error:
        raise gr.Error(str(error)) from error
    except Exception as error:
        raise gr.Error("PFF inference failed") from error


with gr.Blocks(title="PFF-PK inference API") as demo:
    gr.Markdown(
        "# PFF-PK inference API\n"
        "Server-side zero-shot PK cohort generation for the "
        "[PFF dashboard](https://dfaroughy.github.io/pff-pk-dashboard/empirical/)."
    )
    request = gr.JSON(label="Inference request", value={})
    result = gr.JSON(label="Inference response")
    run = gr.Button("Run inference", variant="primary")
    run.click(
        inference,
        inputs=request,
        outputs=result,
        api_name="inference",
        concurrency_limit=1,
        concurrency_id="pff-inference",
    )
    status = gr.JSON(label="Service status")
    check = gr.Button("Check service")
    check.click(health, inputs=None, outputs=status, api_name="health")
    synthetic_run = gr.Button("Generate synthetic cohort")
    synthetic_run.click(synthetic, inputs=request, outputs=result, api_name="synthetic",
                        concurrency_limit=1, concurrency_id="pff-inference")

demo.queue(max_size=32, default_concurrency_limit=1)

if __name__ == "__main__":
    demo.launch()