import gradio as gr import requests import base64 import os # argparse 的简单替代,如有需要可替换为 argparse from argparse import Namespace # 假设 libra_eval 在你的 python 包 libra.eval 中 from libra.eval import libra_eval # 预定义图像及其链接(或者本地路径) DEFAULT_IMAGES = { "Image 1": "https://drive.google.com/uc?export=view&id=10bvR7a4WSyDAtWsNQUjPSs1GlcSxtP81", "Image 2": "https://drive.google.com/uc?export=view&id=1yzKM1eo8yBAGRcm7ayqUhxASXQHNANUa" } ############################################################################### # 如果需要直接使用本地文件,可将以上链接替换为本地路径,比如: # DEFAULT_IMAGES = { # "Image 1": "/path/to/local/file1.jpg", # "Image 2": "/path/to/local/file2.jpg" # } ############################################################################### def image_url_to_base64(image_url: str) -> str: """ 将远程图片 URL 转换为 Base64 数据 URI。 如果请求失败,则返回提示文本。 """ try: response = requests.get(image_url) response.raise_for_status() base64_image = base64.b64encode(response.content).decode("utf-8") return f"data:image/jpeg;base64,{base64_image}" except Exception as e: return f"

Failed to load image: {e}

" def generate_image_html(image_url: str) -> str: """ 生成一个 标签的 HTML,用于在 Gradio 中以预览形式显示图片。 如果是 http(s) 链接,则尝试转换为 Base64;如果是本地路径,直接使用 file://。 """ # 判断是否以 http(s) 开头 if image_url.startswith("http"): base64_image = image_url_to_base64(image_url) return f'' else: # 直接使用本地路径 return f'' def generate_radiology_description( prompt: str, selected_current: str, uploaded_current: str, selected_prior: str, uploaded_prior: str, temperature: float, top_p: float, num_beams: int, max_new_tokens: int ) -> str: """ 核心推理函数: 1. 获取用户输入或默认图片 2. 调用 libra_eval 来生成报告描述 3. 返回生成的结果或错误消息 """ # 如果用户上传了图片,则优先使用上传的图片;否则使用默认图片 current_image = uploaded_current if uploaded_current else DEFAULT_IMAGES.get(selected_current) prior_image = uploaded_prior if uploaded_prior else DEFAULT_IMAGES.get(selected_prior) # 确保用户选择或上传了两张图片 if not current_image or not prior_image: return "Please select or upload both current and prior images." # 模型路径(示例) model_path = "/nfs/LLaVA-ai4bio/gla-biomed-playground/final_model/finetuned_model/llava-libra-test" conv_mode = "libra_v1" try: # 调用 libra_eval 进行推理 output = libra_eval( model_path=model_path, model_base=None, image_file=[current_image, prior_image], query=prompt, temperature=temperature, top_p=top_p, num_beams=num_beams, length_penalty=1.0, num_return_sequences=1, conv_mode=conv_mode, max_new_tokens=max_new_tokens ) return output except Exception as e: return f"An error occurred: {str(e)}" # 在 Gradio 中构建 UI # Blocks 为最新的容器API,可以更好地对布局进行控制 with gr.Blocks() as demo: # 标题和简单说明 gr.Markdown("# Libra Radiology Report Generator") gr.Markdown("Use **Libra** to generate radiology image descriptions. Provide a **Current** and a **Prior** image below.") # 用户输入的文本 with gr.Row(): prompt_input = gr.Textbox( label="Prompt", value="Provide a detailed description of the findings in the radiology image." ) # 当前图像(Current Image)和历史对比图像(Prior Image) with gr.Row(): with gr.Column(): gr.Markdown("### Current Image") # 预览默认图像 for img in DEFAULT_IMAGES.values(): gr.HTML(generate_image_html(img)) # 在Radio中选择 selected_current = gr.Radio( label="Select Current Image", choices=list(DEFAULT_IMAGES.keys()), value="Image 1" ) # 或者上传一张新的 uploaded_current = gr.Image( label="Or Upload Current Image", type="filepath", tool="editor" ) with gr.Column(): gr.Markdown("### Prior Image") # 同样显示默认图像 for img in DEFAULT_IMAGES.values(): gr.HTML(generate_image_html(img)) selected_prior = gr.Radio( label="Select Prior Image", choices=list(DEFAULT_IMAGES.keys()), value="Image 2" ) uploaded_prior = gr.Image( label="Or Upload Prior Image", type="filepath", tool="editor" ) # 一些可调参数 with gr.Row(): temperature_slider = gr.Slider( label="Temperature", minimum=0.1, maximum=1.0, step=0.1, value=0.7 ) top_p_slider = gr.Slider( label="Top P", minimum=0.1, maximum=1.0, step=0.1, value=0.8 ) num_beams_slider = gr.Slider( label="Number of Beams", minimum=1, maximum=20, step=1, value=2 ) max_tokens_slider = gr.Slider( label="Max New Tokens", minimum=10, maximum=4096, step=10, value=128 ) # 用于显示模型生成的结果 output_text = gr.Textbox( label="Generated Description", lines=10 ) # 点击按钮时触发的推理逻辑 generate_button = gr.Button("Generate Description") generate_button.click( fn=generate_radiology_description, inputs=[ prompt_input, selected_current, uploaded_current, selected_prior, uploaded_prior, temperature_slider, top_p_slider, num_beams_slider, max_tokens_slider ], outputs=output_text ) # 启动 Gradio 应用(将 share 设置为 True 以便在 Hugging Face Spaces 中分享) if __name__ == "__main__": demo.launch(share=True)