File size: 5,213 Bytes
64c6b78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d98e26f
64c6b78
d98e26f
64c6b78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d98e26f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d0230aa
 
08ad240
 
 
 
 
958a3b5
64c6b78
958a3b5
d98e26f
 
 
958a3b5
 
 
64c6b78
958a3b5
64c6b78
 
d98e26f
d0230aa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d98e26f
d0230aa
55ff977
d0230aa
 
d98e26f
d0230aa
55ff977
d0230aa
 
d98e26f
d0230aa
55ff977
d0230aa
 
64c6b78
 
958a3b5
 
 
64c6b78
958a3b5
 
64c6b78
 
 
d98e26f
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import gradio as gr
import spaces
import json
import hashlib
import logging
from functools import lru_cache
from transformers import pipeline

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

_pipeline_cache = {"hash": None, "pipe": None, "config": None}

def _hash_config(cfg: dict) -> str:
    return hashlib.sha256(json.dumps(cfg, sort_keys=True).encode()).hexdigest()[:16]

@lru_cache(maxsize=3)
def _load_pipeline(hash_key: str, cfg_json: str):
    cfg = json.loads(cfg_json)
    logger.info(f"Loading pipeline: {cfg}")
    pipe = pipeline(**cfg)
    logger.info("Loaded.")
    return pipe

def get_pipe(cfg: dict):
    h = _hash_config(cfg)
    if _pipeline_cache["hash"] == h and _pipeline_cache["pipe"] is not None:
        return _pipeline_cache["pipe"], False
    pipe = _load_pipeline(h, json.dumps(cfg, sort_keys=True))
    _pipeline_cache.update({"hash": h, "pipe": pipe, "config": cfg})
    return pipe, True

@spaces.GPU(duration=40)
def inference(pipeline_config, inputs, inference_kwargs=None):
    if inference_kwargs is None:
        inference_kwargs = {}
    try:
        pconf = json.loads(pipeline_config) if isinstance(pipeline_config, str) else pipeline_config
    except Exception as e:
        return json.dumps({"error": f"Bad pipeline_config: {e}"})
    try:
        ikw = json.loads(inference_kwargs) if isinstance(inference_kwargs, str) else inference_kwargs
    except Exception as e:
        return json.dumps({"error": f"Bad inference_kwargs: {e}"})

    try:
        pipe, reloaded = get_pipe(pconf)
    except Exception as e:
        return json.dumps({"error": f"Pipeline load failed: {e}"})

    try:
        raw = json.loads(inputs) if isinstance(inputs, str) and inputs.strip().startswith(("[", "{")) else inputs
    except:
        raw = inputs

    try:
        result = pipe(raw, **ikw)
        return json.dumps({
            "success": True,
            "reloaded": reloaded,
            "result": result,
        }, default=str, indent=2)
    except Exception as e:
        return json.dumps({"error": f"Inference failed: {e}"})

# Example configs
EX1 = {
    "pipeline_config": {"task": "text-generation", "model": "HuggingFaceTB/SmolLM2-135M-Instruct"},
    "inputs": "The future of AI is",
    "inference_kwargs": {"max_new_tokens": 50},
}
EX2 = {
    "pipeline_config": {"task": "zero-shot-classification", "model": "facebook/bart-large-mnli"},
    "inputs": "This is a contract about data privacy and user rights.",
    "inference_kwargs": {"candidate_labels": ["legal", "finance", "technology", "sports"]},
}
EX3 = {
    "pipeline_config": {"task": "token-classification", "model": "openai/privacy-filter"},
    "inputs": "My name is Alice Smith",
    "inference_kwargs": {},
}

def run_example(ex):
    result = inference(ex["pipeline_config"], ex["inputs"], ex["inference_kwargs"])
    return ex["pipeline_config"], ex["inputs"], ex["inference_kwargs"], result

with gr.Blocks(title="Dynamic Transformers Pipeline API") as demo:
    gr.Markdown(
        "# 🚀 Dynamic Transformers Pipeline API\n"
        "[Continue AI conversation to edit](https://huggingface.co/chat/conversation/6a751b859a0b83e84c4abd74)\n\n"
        "Zero-GPU. Pass any `transformers.pipeline` config via JSON."
    )

    with gr.Row():
        with gr.Column(scale=1):
            pcfg = gr.JSON(label="pipeline_config", value=EX1["pipeline_config"])
            inp = gr.Textbox(label="inputs", value=EX1["inputs"], lines=3)
            ikw = gr.JSON(label="inference_kwargs", value=EX1["inference_kwargs"])
            btn = gr.Button("▶️ Run Inference", variant="primary")

        with gr.Column(scale=1):
            out = gr.JSON(label="output")

    btn.click(inference, [pcfg, inp, ikw], out)

    gr.Markdown("## 📝 Examples (click to populate & run)")
    with gr.Row():
        with gr.Column():
            gr.Markdown("**Text Generation**")
            ex1_btn = gr.Button("Run: SmolLM2 text-gen", size="sm")
            ex1_out = gr.JSON(label="result")

        with gr.Column():
            gr.Markdown("**Zero-Shot Classification**")
            ex2_btn = gr.Button("Run: zero-shot", size="sm")
            ex2_out = gr.JSON(label="result")

        with gr.Column():
            gr.Markdown("**Token Classification (Privacy Filter)**")
            ex3_btn = gr.Button("Run: privacy-filter", size="sm")
            ex3_out = gr.JSON(label="result")

    ex1_btn.click(
        fn=lambda: run_example(EX1),
        inputs=None,
        outputs=[pcfg, inp, ikw, ex1_out],
    )
    ex2_btn.click(
        fn=lambda: run_example(EX2),
        inputs=None,
        outputs=[pcfg, inp, ikw, ex2_out],
    )
    ex3_btn.click(
        fn=lambda: run_example(EX3),
        inputs=None,
        outputs=[pcfg, inp, ikw, ex3_out],
    )

    gr.Markdown("## API Example")
    gr.Code("""from gradio_client import Client

client = Client("DoctorSlimm/dynamic-transformers-api")
print(client.predict(
    pipeline_config={"task": "text-generation", "model": "HuggingFaceTB/SmolLM2-135M-Instruct"},
    inputs="The future of AI is",
    inference_kwargs={"max_new_tokens": 50},
    api_name="/inference"
))""", language="python")

demo.launch()