import gradio as gr import uuid import asyncio from substra_launcher import launch_substra_space from huggingface_hub import HfApi hf_api = HfApi() theme = gr.themes.Default(primary_hue="blue").set( background_fill_primary="#F9F2EA", block_background_fill="#FFFFFF", ) async def launch_experiment(hospital_a, hospital_b): experiment_id = str(uuid.uuid4()) asyncio.create_task(launch_substra_space( hf_api=hf_api, repo_id=experiment_id, hospital_a=hospital_a, hospital_b=hospital_b, )) url = f"https://hf.space/owkin/trainer-{experiment_id}" return ( gr.Button.update(interactive=False), gr.Markdown.update( visible=True, value=f"Your experiment is available at [hf.space/owkin/trainer-{experiment_id}]({url})!" ) gr.Markdown.update( visible=True, value="If the image does not build in under a minute, please refresh and try again" ) ) demo = gr.Blocks(theme=theme, css="""\ @font-face { font-family: "Didact Gothic"; src: url('https://huggingface.co/datasets/NimaBoscarino/assets/resolve/main/substra/DidactGothic-Regular.ttf') format('truetype'); } @font-face { font-family: "Inter"; src: url('https://huggingface.co/datasets/NimaBoscarino/assets/resolve/main/substra/Inter-Regular.ttf') format('truetype'); } h1 { font-family: "Didact Gothic"; font-size: 40px !important; } p { font-family: "Inter"; } .gradio-container { min-width: 100% !important; } .margin-top { margin-top: 20px; } .white { background-color: white; } .column { border-radius: 20px; padding: 30px; } .blue { background-image: url("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/substra-banner.png"); background-size: cover; } .blue p { color: white !important; } .blue strong { color: white !important; } .info-box { background: transparent !important; border-radius: 20px !important; border-color: white !important; border-width: 4px !important; padding: 20px !important; } """) with demo: gr.HTML(""" """) gr.Markdown("# Federated Learning with Substra") with gr.Row(): with gr.Column(scale=1, elem_classes=["blue", "column"]): gr.Markdown("Here you can run a **quick simulation of Federated Learning**.") gr.Markdown("Check out the accompanying blog post to learn more.") with gr.Box(elem_classes=["info-box"]): gr.Markdown("""\ This space is an introduction to federated learning. \ We will create new spaces soon where you will be able to control the models, datasets and \ federation strategies.\ """) with gr.Column(scale=3, elem_classes=["white", "column"]): gr.Markdown("""\ Data scientists doing medical research often face a shortage of high quality and diverse data to \ effectively train models. This challenge can be overcome by securely allowing training on protected \ data through Federated Learning. [Substra](https://docs.substra.org/) is a Python based Federated \ Learning software that enables researchers to easily train ML models on remote data regardless of the \ ML library they are using or the data type they are working with. """) gr.Markdown("### Here we show an example of image data located in **two different hospitals**.") gr.Markdown("""\ By playing with the distribution of data in the two simulated hospitals, you'll be able to compare how \ the federated models compare with models trained on single datasets. The data used is from the \ Camelyon17 dataset, a commonly used benchmark in the medical world that comes from \ [this challenge](https://camelyon17.grand-challenge.org/). The sample below shows normal cells on the \ left compared with cancer cells on the right. """) gr.HTML(""" """) gr.Markdown("""\ A problem often faced by researchers is that datasets lack the necessary amount of positive samples \ (samples containing cancer tissues) that are needed to reliably classify cancer. In this interface you \ can use the slider to control the percentage of negative and positive samples in each hospital. \ Setting this slider to minimum will mean there are 0 positive samples, whereas 50 would mean that \ half the dataset contains slides with positive tumor samples.\ """) with gr.Row(elem_classes=["margin-top"]): hospital_a_slider = gr.Slider( label="Percentage of positive samples in Hospital A", value=50, ) hospital_b_slider = gr.Slider( label="Percentage of positive samples in Hospital B", value=50, ) launch_experiment_button = gr.Button(value="Launch Experiment 🚀") visit_experiment_text = gr.Markdown(visible=False) launch_experiment_button.click( fn=launch_experiment, inputs=[hospital_a_slider, hospital_b_slider], outputs=[launch_experiment_button, visit_experiment_text] ) demo.launch()