×
Community Blog การสร้างภาพและวิดีโอจากพรอมต์โดยใช้โมเดลตัวอย่าง Wan 2.5 จาก Model Studio

การสร้างภาพและวิดีโอจากพรอมต์โดยใช้โมเดลตัวอย่าง Wan 2.5 จาก Model Studio

บทความนี้จะแนะนำการสาธิตการใช้งาน Gradio บน ECS ของ Alibaba Cloud เพื่อสร้างรูปภาพและวิดีโอด้วยโมเดล Wan 2.5 ใน Model Studio ผ่านการบูรณาการคีย์ API

โดย Ferdin Joe

การสาธิตนี้มีไว้เพื่อสร้างอินเทอร์เฟซ Gradio ใน Alibaba Cloud Elastic Compute Service (ECS) และช่วยให้ Gradio สามารถเชื่อมต่อกับโมเดลตัวอย่าง Wan 2.5 ใน Alibaba Cloud Model Studio โดยใช้คีย์ API เพื่อสร้างรูปภาพและวิดีโอตามพรอมต์ที่ระบุไว้เป็นอินพุต การสาธิตนี้ประกอบด้วยส่วนต่อไปนี้:

● การสร้างอินสแตนซ์ ECS

● การพัฒนาโค้ดสำหรับ Gradio

● การติดตั้งโค้ดใน ECS โดยใช้สคริปต์ Bash

●·คู่มือการใช้งานโซลูชัน

การสร้างอินสแตนซ์ ECS

สร้างอินสแตนซ์ ECS ด้วยการกำหนดค่าปกติด้วยที่อยู่ IP สาธารณะหรือ EIP IP ที่คนทั่วไปใช้ได้มีการจัดสรรแบนด์วิดท์ไว้เป็นอย่างดี เพิ่มอินสแตนซ์ในกลุ่มรักษาความปลอดภัยที่คุณอนุญาตให้พอร์ต 7860 ในการเชื่อมต่อขาเข้า

image

กฎอื่นๆ สำหรับกฎขาเข้าและขาออกเป็นไปตามปกติ

การพัฒนาโค้ดสำหรับ Gradio

Gradio ใช้ไพธอนและจำเป็นต้องติดตั้งการพึ่งพาที่จำเป็น จำเป็นต้องใช้คีย์ API ของ Model Studio สร้างคีย์จากคอนโซลของ Model Studio เราต้องการส่วนประกอบของโค้ดต่อไปนี้:

ชื่อไฟล์: .env

โค้ดนี้มีไว้เพื่อจัดเก็บคีย์ API สำหรับดึงคำขอออกมา

DASHSCOPE_API_KEY=<Your Model Studio API Key>

ชื่อไฟล์: gradio_wan_app.py

#!/usr/bin/env python3
"""
อินเทอร์เฟซเว็บ Gradio สำหรับการสร้างข้อความเป็นรูปภาพของ Wan
การใช้ API ของ DashScope Model Studio
"""

from http import HTTPStatus
from urllib.parse import urlparse, unquote
from pathlib import PurePosixPath
import requests
from dashscope import ImageSynthesis, VideoSynthesis
from dashscope.audio.tts_v2 import SpeechSynthesizer
import os
import dashscope
import gradio as gr
from dotenv import load_dotenv
from PIL import Image
from io import BytesIO
import logging
import json

# ตั้งค่าการบันทึกข้อมูล
logging.basicConfig(
  level=logging.INFO,
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# โหลดตัวแปรสภาพแวดล้อม
load_dotenv()

# การกำหนดค่า - ใช้ API ของภูมิภาคสิงคโปร์
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

# รับคีย์ API จากสภาพแวดล้อม
DASHSCOPE_API_KEY = os.getenv("DASHSCOPE_API_KEY", "<Model Studio API>")
dashscope.api_key = DASHSCOPE_API_KEY

logger.info(f"🚀 Gradio WAN Image Generator starting...")
logger.info(f"API Endpoint: {dashscope.base_http_api_url}")


def generate_image(
  prompt: str,
  negative_prompt: str = "",
  num_images: int = 1,
  size: str = "1024*1024",
  seed: int = None,
  prompt_extend: bool = True,
  watermark: bool = False
):
  """
    สร้างรูปภาพโดยใช้โมเดล WAN 2.5
    
    Args:
        prompt: Text description of the image to generate
        negative_prompt: What to avoid in the image
        num_images: Number of images to generate (1-4)
        size: Image size (1024*1024, 720*1280, 1280*720)
        seed: Random seed for reproducibility (optional)
        prompt_extend: Whether to automatically expand the prompt
        watermark: Whether to add watermark
    
    Returns:
        List of PIL Images or error message
    """
  if not prompt or prompt.strip() == "":
    return None, None, "❌ Please provide a prompt description!"

    try:
      logger.info(f"🎨 Generating image with prompt: {prompt}")

      # เตรียมพารามิเตอร์
      params = {
        'api_key': DASHSCOPE_API_KEY,
        'model': 'wan2.5-t2i-preview',
        'prompt': prompt,
        'negative_prompt': negative_prompt,
        'n': num_images,
        'size': size,
        'prompt_extend': prompt_extend,
        'watermark': watermark
      }

      # เพิ่ม Seed ถ้ามี
      หาก Seed ไม่ใช่ None และ Seed > 0:
        params['seed'] = seed

        # เรียก API ของ WAN
        logger.info(f"Calling WAN 2.5 API with parameters: {params}")
      rsp = ImageSynthesis.call(**params)

      logger.info(f"Response status: {rsp.status_code}")

      if rsp.status_code == HTTPStatus.OK:
        Images = []

        # ดาวน์โหลดและแปลงรูปภาพที่สร้างขึ้นแต่ละรายการ
        for idx, result in enumerate(rsp.output.results):
          logger.info(f"Downloading image {idx + 1}: {result.url}")

          # ดาวน์โหลดข้อมูลรูปภาพ
          image_data = requests.get(result.url).content

          # แปลงเป็นรูปภาพ PIL
          image = Image.open(BytesIO(image_data))
          images.append(image)

          logger.info(f"✅ Image {idx + 1} downloaded successfully")

          success_msg = f"✅ Successfully generated {len(images)} image(s)!"
        # ส่งกลับเป็นรายการสำหรับองค์ประกอบแกลเลอรี่เสมอ
        return images, None, success_msg
      else:
        error_msg = f"❌ Generation failed!\n\nStatus: {rsp.status_code}\nCode: {rsp.code}\nMessage: {rsp.message}"
        logger.error(error_msg)
        return None, None, error_msg

    except Exception as e:
      error_msg = f"❌ Error during image generation:\n\n{str(e)}"
      logger.error(f"Error in generate_image: {e}", exc_info=True)
      return None, None, error_msg


def generate_video(
  prompt: str,
  resolution: str = "1280*720",
  duration: str = "5s",
  enable_audio: bool = False
):
  """
    สร้างวิดีโอโดยใช้โมเดล WAN 2.5 T2V Preview
    
    Args:
        prompt: Text description of the video to generate
        resolution: Video resolution (1280*720, 960*960, 1280*768, 768*1280)
        duration: Video duration (5s or 10s)
        enable_audio: Whether to generate audio for the video
    
    Returns:
        Video file path and status message
    """
  if not prompt or prompt.strip() == "":
    return None, None, "❌ Please provide a prompt description!"

    try:
      logger.info(f"🎬 Generating video with prompt: {prompt}")
      logger.info(f"Using WAN 2.5 T2V Preview model with resolution: {resolution}")
      logger.info(f"Duration: {duration}")
      logger.info(f"Audio enabled: {enable_audio}")

      # เรียก API ของ WAN 2.5 T2V Preview โดยใช้ VideoSynthesis
      # หมายเหตุ: การสร้างเสียงทำผ่านพารามิเตอร์แยกต่างหาก
      logger.info("Calling VideoSynthesis API...")

      # แปลงสตริงระยะเวลาเป็นวินาที (เช่น "10s" -> 10)
      duration_seconds = int(duration.replace('s', ''))

      if enable_audio:
        # ใช้โมเดลที่รองรับเสียง
        rsp = VideoSynthesis.call(
          model='wan2.5-t2v-preview',
          prompt=prompt,
          size=resolution,
          duration=duration_seconds,
          audio=True  # Enable audio generation
        )
      else:
        # วิดีโอมาตรฐานที่ไม่มีเสียง
        rsp = VideoSynthesis.call(
          model='wan2.5-t2v-preview',
          prompt=prompt,
          size=resolution,
          duration=duration_seconds
        )

        logger.info(f"Response status: {rsp.status_code}")

      if rsp.status_code == HTTPStatus.OK:
        video_url = rsp.output.video_url
        logger.info(f"Video URL received: {video_url}")

        # ดาวน์โหลดวิดีโอ
        logger.info("Downloading video...")
        video_data = requests.get(video_url).content

        # บันทึกเป็นไฟล์
        import time
        video_filename = f"generated_video_{int(time.time())}.mp4"
        with open(video_filename, 'wb') as f:
          f.write(video_data)

          logger.info(f"✅ Video downloaded successfully: {video_filename}")
        audio_status = " with audio" if enable_audio else " (no audio)"
        success_msg = f"✅ Successfully generated video{audio_status}!\n\nDuration: {duration}\nResolution: {resolution}\nModel: WAN 2.5 T2V Preview"
        return None, video_filename, success_msg
      else:
        error_msg = f"❌ Video generation failed!\n\nStatus: {rsp.status_code}\nCode: {rsp.code}\nMessage: {rsp.message}\n\nNote: Video generation may not be available with your current API key."
        logger.error(error_msg)
        logger.error(f"Full response: status_code={rsp.status_code}, code={rsp.code}, message={rsp.message}")
        return None, None, error_msg

    except Exception as e:
      error_msg = f"❌ Error during video generation:\n\n{str(e)}\n\nNote: Video generation requires API access to WAN T2V models."
      logger.error(f"Error in generate_video: {e}", exc_info=True)
      return None, None, error_msg


def generate_content(
  mode: str,
  prompt: str,
  negative_prompt: str,
  num_images: int,
  image_size: str,
  video_resolution: str,
  video_duration: str,
  enable_audio: bool,
  seed: int,
  prompt_extend: bool,
  watermark: bool
):
  """
    นำไปยังฟังก์ชันการสร้างที่เหมาะสมตามโหมด
    """
  if mode == "Text to Image":
    return generate_image(
      prompt=prompt,
      negative_prompt=negative_prompt,
      num_images=num_images,
      size=image_size,
      seed=seed,
      prompt_extend=prompt_extend,
      watermark=watermark
    )
  else:  # Text to Video
    return generate_video(
      prompt=prompt,
      resolution=video_resolution,
      duration=video_duration,
      enable_audio=enable_audio
    )


# สร้างอินเทอร์เฟซ Gradio
def create_interface():
  """Create and configure the Gradio interface"""

  with gr.Blocks(
    title="WAN Text-to-Image & Text-to-Video Generator",
    theme=gr.themes.Soft()
  ) as demo:
    gr.Markdown(
      """
            # 🎨 เครื่องมือสร้างข้อความเป็นรูปภาพและข้อความเป็นวิดีโอของ WAN 2.5
            
            สร้างรูปภาพหรือวิดีโอที่สวยงามจากข้อความอธิบายโดยใช้โมเดล Wan ของ Alibaba Cloud
            
            ### วิธีใช้:
            1.  เลือกโหมดการสร้าง (รูปภาพหรือวิดีโอ)
            2.  ป้อนคำอธิบายโดยละเอียด
            3.  (ไม่จำเป็น) ปรับการตั้งค่า
            4.  คลิกปุ่ม **Generate** (สร้าง)
            5.  รอผลงานที่คุณสร้าง!  🎞️
            """
    )

    with gr.Row():
      with gr.Column(scale=1):
        # การเลือกโหมด
        mode_radio = gr.Radio(
          choices=["Text to Image", "Text to Video"],
          value="Text to Image",
          label="🎭 Generation Mode",
          info="Choose what you want to generate"
        )

        # การควบคุมอินพุต
        prompt_input = gr.Textbox(
          label="✏️ Prompt",
          placeholder="Describe what you want to generate... (e.g., 'A beautiful sunset over mountains')",
          lines=3,
          max_lines=5
        )

        # การตั้งค่าเฉพาะรูปภาพ
        with gr.Group(visible=True) as image_settings:
          gr.Markdown("### 🖼️ Image Settings")

          negative_prompt_input = gr.Textbox(
            label="🚫 Negative Prompt (Optional)",
            placeholder="What to avoid... (e.g., 'blurry, low quality')",
            lines=2,
            max_lines=3
          )

          num_images_slider = gr.Slider(
            minimum=1,
            maximum=4,
            value=1,
            step=1,
            label="Number of Images"
          )

          image_size_dropdown = gr.Dropdown(
            choices=["1024*1024", "720*1280", "1280*720"],
            value="1024*1024",
            label="Image Size"
          )

          seed_number = gr.Number(
            label="Seed (Optional)",
            value=None,
            precision=0,
            info="Use same seed for reproducible results"
          )

          prompt_extend_checkbox = gr.Checkbox(
            label="Auto-expand Prompt",
            value=True,
            info="Let AI enhance your prompt"
          )

          watermark_checkbox = gr.Checkbox(
            label="Add Watermark",
            value=False
          )

          # การตั้งค่าเฉพาะวิดีโอ
          with gr.Group(visible=False) as video_settings:
            gr.Markdown("### 🎬 Video Settings")

            video_resolution_dropdown = gr.Dropdown(
              choices=["1280*720", "960*960", "1280*768", "768*1280"],
              value="1280*720",
              label="Video Resolution"
            )

            video_duration_radio = gr.Radio(
              choices=["5s", "10s"],
              value="5s",
              label="Video Duration",
              info="Longer videos take more time to generate"
            )

            enable_audio_checkbox = gr.Checkbox(
              label="🔊 Enable Audio",
              value=False,
              info="Generate audio for video (Note: Audio support depends on API availability)"
            )

            generate_btn = gr.Button(
              "🎨 Generate",
              variant="primary",
              size="lg"
            )

        status_output = gr.Textbox(
          label="Status",
          interactive=False,
          show_label=True
        )

        with gr.Column(scale=1):
          # การแสดงผลเอาต์พุต
          image_output = gr.Gallery(
            label="Generated Images",
            show_label=True,
            visible=True,
            columns=2,
            rows=2,
            object_fit="contain"
          )

          video_output = gr.Video(
            label="Generated Video",
            show_label=True,
            visible=False
          )

      # ตัวอย่างพรอมต์
      gr.Markdown("### 💡 Example Prompts")

    with gr.Tab("Image Examples"):
      gr.Examples(
        examples=[
          ["A serene Japanese garden with cherry blossoms, koi pond, and traditional pagoda at sunset"],
          ["A futuristic cyberpunk city with neon lights, flying cars, and towering skyscrapers"],
          ["A cozy coffee shop interior with warm lighting, wooden furniture, and plants"],
          ["A majestic dragon flying over snow-capped mountains under the northern lights"],
          ["A cute robot reading a book in a library filled with ancient tomes"],
        ],
        inputs=[prompt_input]
      )

      with gr.Tab("Video Examples"):
        gr.Examples(
          examples=[
            ["A time-lapse of clouds moving across a blue sky over a mountain landscape"],
            ["Ocean waves gently rolling onto a sandy beach at sunset"],
            ["A butterfly landing on a flower and slowly opening its wings"],
            ["Rain drops falling on a window with a blurred city background"],
            ["Northern lights dancing in the night sky over a snowy landscape"],
          ],
          inputs=[prompt_input]
        )

        # สลับการมองเห็นตามโหมด
        def update_visibility(mode):
          if mode == "Text to Image":
            return (
              gr.update(visible=True),   # image_settings
              gr.update(visible=False),  # video_settings
              gr.update(visible=True),   # image_output
              gr.update(visible=False),  # video_output
              gr.update(value="🎨 Generate Image")  # button text
            )
          else:
            return (
              gr.update(visible=False),  # image_settings
              gr.update(visible=True),   # video_settings
              gr.update(visible=False),  # image_output
              gr.update(visible=True),   # video_output
              gr.update(value="🎬 Generate Video")  # button text
            )

    mode_radio.change(
      fn=update_visibility,
      inputs=[mode_radio],
      outputs=[image_settings, video_settings, image_output, video_output, generate_btn]
    )

    # เชื่อมต่อปุ่มสร้าง
    generate_btn.click(
      fn=generate_content,
      inputs=[
        mode_radio,
        prompt_input,
        negative_prompt_input,
        num_images_slider,
        image_size_dropdown,
        video_resolution_dropdown,
        video_duration_radio,
        enable_audio_checkbox,
        seed_number,
        prompt_extend_checkbox,
        watermark_checkbox
      ],
      outputs=[image_output, video_output, status_output]
    )

    return demo


if __name__ == "__main__":
  # ตรวจสอบคีย์ API
  if not DASHSCOPE_API_KEY or DASHSCOPE_API_KEY == "":
    logger.error("❌ DASHSCOPE_API_KEY not found in environment variables!")
    print("\n⚠️  Please set DASHSCOPE_API_KEY in your .env file\n")
    exit(1)

    # สร้างและเปิดใช้อินเทอร์เฟซ
    demo = create_interface()

  logger.info("🌐 Launching Gradio interface...")
  demo.launch(
    server_name="0.0.0.0",
    server_port=7860,
    share=False,
    show_error=True
  )

ชื่อไฟล์: deploy_to_ecs.sh

#!/bin/bash
# สคริปต์การใช้งานสำหรับแอป Gradio WAN บน Alibaba Cloud ECS
# เรียกใช้สคริปต์นี้บนอินสแตนซ์ ECS ของคุณหลังจากถ่ายโอนไฟล์

set -e  # Exit on error

echo "🚀 Starting deployment of Gradio WAN App..."

# สีสำหรับเอาต์พุต
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m' # No Color

# การกำหนดค่า
APP_DIR="/root/financeapp"
SERVICE_NAME="gradio-wan"

echo -e "${BLUE}📦 Step 1: Installing system dependencies...${NC}"
if command -v apt &> /dev/null; then
    # Ubuntu/Debian
    sudo apt update
    sudo apt install -y python3 python3.12-venv python3-pip git build-essential
elif command -v yum &> /dev/null; then
    # CentOS/RHEL
    sudo yum update -y
    sudo yum install -y python39 python39-pip git gcc gcc-c++ make
fi

echo -e "${BLUE}📂 Step 2: Setting up application directory...${NC}"
cd $APP_DIR

echo -e "${BLUE}🐍 Step 3: Creating Python virtual environment...${NC}"
python3 -m venv .venv
source .venv/bin/activate

echo -e "${BLUE}📥 Step 4: Installing Python dependencies...${NC}"
pip install --upgrade pip
pip install gradio==4.16.0 gradio-client==0.8.1
pip install dashscope>=1.23.4
pip install python-dotenv>=1.0.0
pip install requests>=2.31.0
pip install pillow>=10.0.0
pip install "huggingface_hub<1.0.0"
pip install numpy>=1.24.0

echo -e "${BLUE}⚙️  Step 5: Creating systemd service...${NC}"
sudo tee /etc/systemd/system/${SERVICE_NAME}.service > /dev/null <<EOF
[หน่วย]
Description=Gradio WAN Image and Video Generator
After=network.target

[บริการ]
Type=simple
User=root
WorkingDirectory=$APP_DIR
Environment="PATH=$APP_DIR/.venv/bin"
ExecStart=$APP_DIR/.venv/bin/python gradio_wan_app.py
Restart=always
RestartSec=10
StandardOutput=append:/var/log/${SERVICE_NAME}.log
StandardError=append:/var/log/${SERVICE_NAME}.error.log

[ติดตั้ง]
WantedBy=multi-user.target
EOF

echo -e "${BLUE}🔄 Step 6: Enabling and starting service...${NC}"
sudo systemctl daemon-reload
sudo systemctl enable ${SERVICE_NAME}
sudo systemctl restart ${SERVICE_NAME}

echo -e "${GREEN}✅ Deployment completed successfully!${NC}"
echo ""
echo "📊 Service Status:"
sudo systemctl status ${SERVICE_NAME} --no-pager

echo ""
echo "🌐 Your Gradio app should now be accessible at:"
echo "   http://$(curl -s ifconfig.me):7860"
echo ""
echo "📝 Useful commands:"
echo "   View logs:     sudo journalctl -u ${SERVICE_NAME} -f"
echo "   Stop service:  sudo systemctl stop ${SERVICE_NAME}"
echo "   Start service: sudo systemctl start ${SERVICE_NAME}"
echo "   Restart:       sudo systemctl restart ${SERVICE_NAME}"
echo "   Status:        sudo systemctl status ${SERVICE_NAME}"
echo ""
echo "⚠️  Important: Make sure port 7860 is open in your ECS security group!"

โหลด 3 ไฟล์ข้างต้นลงในโฟลเดอร์รากที่กำหนดไว้ด้วยสภาพแวดล้อมเสมือนจริง .venv. คำสั่งสำหรับการติดตั้งทุกอย่างที่จำเป็นจะระบุไว้ในส่วนถัดไป

การติดตั้งโค้ดใน ECS โดยใช้สคริปต์ Bash

อัปโหลดไฟล์ลงใน ECS โดยใช้คำสั่งต่อไปนี้จากเทอร์มินัลภายในของคุณ

# ถ่ายโอนไฟล์ที่จำเป็นทั้งหมด (แทนที่ <ECS_IP> ด้วย IP สาธารณะ ECS จริงของคุณ)
scp gradio_wan_app.py root@<ECS_IP>:/root/targetfolder/
scp .env root@<ECS_IP>:/root/targetfolder/
scp deploy_to_ecs.sh root@<ECS_IP>:/root/targetfolder/

หากต้องการติดตั้งทุกอย่างที่จำเป็น นับตั้งแต่ Python, pip, สภาพแวดล้อมเสมือน และไลบรารีที่จำเป็น ให้เรียกใช้คำสั่งต่อไปนี้

cd /root/targetfolder
chmod +x deploy_to_ecs.sh
./deploy_to_ecs.sh

คำสั่งนี้จะเรียกใช้เชลล์สคริปต์และทำให้สามารถเรียกใช้อินเทอร์เฟซได้ด้วยที่อยู่ต่อไปนี้: http://ECS-Public-IP:7860

blog1

สำหรับการแปลงข้อความเป็นรูปภาพ คุณสามารถสร้างรูปภาพได้ 4 รายการในเวลาเดียวกัน สำหรับการแปลงข้อความเป็นวิดีโอ คุณสามารถสร้างวิดีโอ Wan ที่มีความละเอียดแตกต่างกัน เปิดใช้งาน/ปิดใช้งานเสียงและรับวิดีโอความยาว 5 หรือ 10 วินาทีได้ แอปพลิเคชันนี้พัฒนาโดยใช้ Qoder IDE โดยใช้โหมดเอเจนต์


บทความนี้เป็นฉบับแปลจากต้นฉบับภาษาอังกฤษ หากต้องการดูเนื้อหาตั้งต้น โปรดไปที่: https://www.alibabacloud.com/blog/image-and-video-generation-from-text-prompts-using-wan-2-5-preview-model-from-model-studio_602726

0 0 0
Share on

Regional Content Hub

129 posts | 4 followers

You may also like

Comments

Regional Content Hub

129 posts | 4 followers

Related Products