Gemma-3n-E4B-it本地部署教程:谷歌开源轻量级多模态大模型,碾压 17B 级同类模型!

一、模型介绍

Gemma-3n-E4B-it(简称 E4B-IT)是 Google 于 2025 年 6 月 26 日推出的轻量级开源多模态 AI 模型,属于 Gemma 3n 系列的高阶版本(E4B 指“有效参数 4B”),专为移动设备和边缘计算场景设计,支持本地处理文本、图像和音频输入,并生成文本输出 。

E4B-IT 的音频功能支持设备端语音转文本和翻译(英法/英西翻译准确率超 92%),视觉功能由 MobileNet-V5 编码器驱动 。其 KV 缓存共享技术优化了长上下文处理速度,预填充性能提升 2 倍,支持 32K 上下文长度 。

Gemma 3n模型具有多种架构创新:

  • 它们有两种大小可供选择,基于有效参数。虽然此模型的原始参数数量为8B,但其架构设计允许通过将低利用率矩阵从加速器中卸载来以与传统4B模型相当的内存占用运行模型。
  • 它们使用MatFormer架构,允许在E4B模型内嵌套子模型。我们提供了一个子模型(一个E2B),或者您可以使用Mix-and-Match方法访问一系列自定义大小的模型。

其输入与输出
输入:

  1. 文本字符串,如问题、提示或待总结的文档;
  2. 图像,归一化为256x256、512x512或768x768分辨率,并编码为每个256个token;
  3. 音频数据,从单声道编码为每秒6.25个token;
  4. 总输入上下文为32K个token。

输出:

  1. 生成的文本作为对输入的响应,如问题的答案、图像内容的分析或文档的摘要;
  2. 总输出长度最多为32K个token,减去请求输入的token。

二、模型部署

基础环境配置推荐

环境名称版本信息
Ubuntu22.04.4 LTS
Python3.12
CUDA12.6
NVIDIA CorporationRTX 4090

注:推荐单卡部署

1.更新基础软件包

查看系统版本信息

#查看系统的版本信息,包括 ID(如 ubuntu、centos 等)、版本号、名称、版本号 ID 等
cat /etc/os-release

image.png

更新软件包列表

#更新软件列表
apt-get update

image.png

2.创建虚拟环境

创建虚拟环境

#创建名为gemma-3n的虚拟环境,python版本:3.12
conda create -n gemma-3n python=3.12

image.png

激活虚拟环境

conda activate gemma-3n

image.png

3.下载依赖

创建并进入文件夹gemma-3n-E4B-it

mkdir gemma-3n-E4B-it
cd /gemma-3n-E4B-it

image.png

安装必要的库文件

pip install -r requirements.txt

requirements.txt文件:

accelerate==1.8.1
gradio==5.24.0
peft==0.16.0
timm==1.0.16
torch==2.7.1
torchvision==0.22.1
transformers==4.53.1
diffusers==0.34.0
soundfile==0.13.1
librosa==0.11.0

4.模型下载

转到魔塔社区官网下载模型文件:gemma-3n-E4B-it · 模型库

image.png

使用命令行下载完整模型库

#在下载前,请先通过如下命令安装
pip install modelscope

image.png

#命令行下载

modelscope download --model ‘google/gemma-3n-E4B-it’ --local_dir ‘/gemma-3n-E4B-it/’

image.png

5.编写web页面启动脚本

编写一个app.py文件,用于模型的web页面启动**(注意:若将文件命名为gradio.py则会引发环境冲突,导致web页面无法正常生成)**

image.png

仓库中并没有明确给出web页面聊天代码,如下是 gradio.py启动脚本的简单示例:

import gradio as gr
from modelscope import AutoProcessor, Gemma3nForConditionalGeneration
from PIL import Image
import torch
import base64
from io import BytesIO
import logging
import os
import platform

# 禁用Gradio的版本检查和遥测
os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"
os.environ["HF_HUB_DISABLE_TELEMETRY"] = "1"

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# 记录系统信息
logger.info(f"Python version: {platform.python_version()}")
logger.info(f"Torch version: {torch.__version__}")
logger.info(f"Gradio version: {gr.__version__}")

# 初始化模型和处理器
model_id = "/gemma-3n-E4B-it/"  # 确保路径存在且正确
device = "cuda" if torch.cuda.is_available() else "cpu"
logger.info(f"Using device: {device}")

try:
    # 加载模型 - 更安全的设备映射
    device_map = "auto" if torch.cuda.is_available() else None
    model = Gemma3nForConditionalGeneration.from_pretrained(
        model_id,
        device_map=device_map,
        torch_dtype=torch.bfloat16 if device == "cuda" else torch.float32,
    ).eval()
    logger.info("Model loaded successfully")
  
    # 如果使用CPU,手动将模型移到设备
    if device_map is None:
        model = model.to(device)
  
    # 加载处理器
    processor = AutoProcessor.from_pretrained(model_id)
    logger.info("Processor loaded successfully")
except Exception as e:
    logger.exception(f"Error loading model or processor")
    raise

def pil_to_base64(img):
    """将PIL图像转换为Base64数据URL"""
    try:
        if img is None:
            return ""
  
        buffered = BytesIO()
        # 转换图像为RGB模式确保兼容性
        if img.mode != "RGB":
            img = img.convert("RGB")
        img.save(buffered, format="JPEG")
        img_str = base64.b64encode(buffered.getvalue()).decode()
        return f"data:image/jpeg;base64,{img_str}"
    except Exception as e:
        logger.exception(f"Image conversion error")
        # 返回1x1透明像素作为占位符
        return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="

def predict(image, user_text):
    try:
        logger.info("Received prediction request")
  
        # 检查图像是否有效
        if image is None:
            return "Please upload an image first"
  
        # 转换PIL图像为Base64 URL
        image_url = pil_to_base64(image)
        logger.info("Image converted to base64")
  
        # 构建对话消息
        messages = [
            {
                "role": "system",
                "content": [{"type": "text", "text": "You are a helpful assistant."}]
            },
            {
                "role": "user",
                "content": [
                    {"type": "image", "url": image_url},
                    {"type": "text", "text": user_text}
                ]
            }
        ]

        # 处理输入
        inputs = processor.apply_chat_template(
            messages,
            add_generation_prompt=True,
            tokenize=True,
            return_dict=True,
            return_tensors="pt",
        ).to(device)

        input_len = inputs["input_ids"].shape[-1]
        logger.info(f"Input processed, length: {input_len}")

        # 生成响应
        with torch.inference_mode():
            logger.info("Generating response...")
            generation = model.generate(
                **inputs, 
                max_new_tokens=200, 
                do_sample=False,
                temperature=0.7,
                top_p=0.9
            )
            generation = generation[0][input_len:]

        # 解码输出
        decoded = processor.decode(generation, skip_special_tokens=True)
        logger.info("Response generated successfully")
        return decoded
  
    except Exception as e:
        logger.exception(f"Prediction error")
        return f"Error generating response: {str(e)}"

# 创建Gradio界面
with gr.Blocks(title="Gemma-3n-e4b-it Demo") as demo:
    gr.Markdown("# 🚀 Gemma-3n-e4b-it Multimodal Demo")
    gr.Markdown("Upload an image and ask questions about it. The model will provide detailed responses.")
  
    with gr.Row():
        with gr.Column(scale=1):
            image_input = gr.Image(
                type="pil", 
                label="Upload Image",
                sources=["upload"]
            )
  
        with gr.Column(scale=2):
            text_input = gr.Textbox(
                lines=3, 
                placeholder="Enter your question here...", 
                label="Your Question",
                max_lines=5
            )
  
            with gr.Row():
                submit_btn = gr.Button("Generate Response", variant="primary")
                clear_btn = gr.Button("Clear Inputs")
  
            output = gr.Textbox(
                label="Model Response", 
                interactive=False,
                show_copy_button=True
            )
  
    # 设置按钮点击事件
    submit_btn.click(
        fn=predict,
        inputs=[image_input, text_input],
        outputs=output
    )
  
    # 清除输入
    clear_btn.click(
        fn=lambda: [None, "", ""],
        inputs=[],
        outputs=[image_input, text_input, output]
    )

if __name__ == "__main__":
    # 配置启动参数
    launch_args = {
        "server_name": "0.0.0.0",
        "server_port": 7860,
        "share": False  # 若需要分享改为True,并手动下载frpc
    }

    # 启动应用
    demo.launch(**launch_args)

6.运行脚本

注:首次运行脚本代码时,需要下载部分示例文件,且模型加载需要等待一段时间,请耐心等待

#执行编写好的app.py文件
python app.py

image.png

image.png

7.web页面展示

将web页面运行网址粘贴到浏览器中,便可与模型进行对话

image.png

  • 多模态对话

屏幕截图

image.png

屏幕截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值