|
|
Chạy trong Google Colab
|
|
Xem nguồn trên GitHub
|
Các mô hình PaliGemma có khả năng đa phương thức, cho phép bạn tạo kết quả đầu ra bằng cả dữ liệu đầu vào là văn bản và hình ảnh. Bạn có thể sử dụng dữ liệu hình ảnh với các mô hình này để cung cấp thêm bối cảnh cho các yêu cầu của mình hoặc sử dụng mô hình để phân tích nội dung của hình ảnh. Hướng dẫn này trình bày cách sử dụng PaliGemma với Keras để phân tích hình ảnh và trả lời các câu hỏi về hình ảnh.
Nội dung của sổ tay này
Sổ tay này sử dụng PaliGemma với Keras và hướng dẫn bạn cách:
- Cài đặt Keras và các phần phụ thuộc bắt buộc
- Tải
PaliGemmaCausalLMxuống, đây là một biến thể PaliGemma được huấn luyện trước để lập mô hình ngôn ngữ trực quan nhân quả và sử dụng biến thể này để tạo mô hình - Kiểm thử khả năng suy luận thông tin về hình ảnh được cung cấp của mô hình
Trước khi bắt đầu
Trước khi xem xét sổ tay này, bạn nên làm quen với mã Python cũng như cách huấn luyện các mô hình ngôn ngữ lớn (LLM). Bạn không cần phải quen thuộc với Keras, nhưng kiến thức cơ bản về Keras sẽ hữu ích khi đọc mã ví dụ.
Thiết lập
Các phần sau đây giải thích các bước sơ bộ để thiết lập một sổ tay nhằm sử dụng mô hình PaliGemma, bao gồm cả quyền truy cập vào mô hình, lấy khoá API và định cấu hình thời gian chạy sổ tay.
Sử dụng PaliGemma
Trước khi sử dụng PaliGemma lần đầu tiên, bạn phải yêu cầu cấp quyền truy cập vào mô hình này thông qua Kaggle bằng cách hoàn tất các bước sau:
- Đăng nhập vào Kaggle hoặc tạo một tài khoản Kaggle mới nếu bạn chưa có.
- Chuyển đến thẻ mô hình PaliGemma rồi nhấp vào Yêu cầu cấp quyền truy cập.
- Hoàn tất biểu mẫu đồng ý và chấp nhận các điều khoản và điều kiện.
Định cấu hình khoá API
Để sử dụng PaliGemma, bạn phải cung cấp tên người dùng Kaggle và khoá API Kaggle.
Để tạo khoá API Kaggle, hãy mở trang Settings (Cài đặt) trong Kaggle rồi nhấp vào Create New Token (Tạo mã thông báo mới). Thao tác này sẽ kích hoạt quá trình tải tệp kaggle.json xuống, trong đó có thông tin đăng nhập API của bạn.
Sau đó, trong Colab, hãy chọn Bí mật (🔑) trong ngăn bên trái rồi thêm tên người dùng Kaggle và khoá API Kaggle. Lưu tên người dùng của bạn dưới tên KAGGLE_USERNAME và khoá API dưới tên KAGGLE_KEY.
Chọn thời gian chạy
Để hoàn tất hướng dẫn này, bạn cần có một môi trường thời gian chạy Colab với đủ tài nguyên để chạy mô hình PaliGemma. Trong trường hợp này, bạn có thể sử dụng GPU T4:
- Ở phía trên bên phải của cửa sổ Colab, hãy nhấp vào trình đơn thả xuống ▾ (Các lựa chọn kết nối khác).
- Chọn Thay đổi loại thời gian chạy.
- Trong phần Trình tăng tốc phần cứng, hãy chọn GPU T4.
Đặt các biến môi trường
Đặt các biến môi trường cho KAGGLE_USERNAME, KAGGLE_KEY và KERAS_BACKEND.
import os
from google.colab import userdata
# Set up environmental variables
os.environ["KAGGLE_USERNAME"] = userdata.get('KAGGLE_USERNAME')
os.environ["KAGGLE_KEY"] = userdata.get('KAGGLE_KEY')
os.environ["KERAS_BACKEND"] = "jax"
Cài đặt Keras
Chạy ô bên dưới để cài đặt Keras.
pip install -U -q keras-nlp keras-hub kagglehubNhập các phần phụ thuộc và định cấu hình Keras
Cài đặt các phần phụ thuộc cần thiết cho sổ tay này và định cấu hình phần phụ trợ của Keras. Bạn cũng sẽ đặt Keras để sử dụng bfloat16 để khung này sử dụng ít bộ nhớ hơn.
import keras
import keras_hub
import numpy as np
import PIL
import requests
import io
import matplotlib
import re
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image
keras.config.set_floatx("bfloat16")
Tải mô hình
Giờ đây, bạn có thể tải mô hình được huấn luyện trước xuống và tạo một số phương thức tiện ích để giúp mô hình tạo ra các câu trả lời.
Trong bước này, bạn sẽ tải một mô hình xuống bằng PaliGemmaCausalLM từ Keras Hub. Lớp này giúp bạn quản lý và chạy cấu trúc mô hình ngôn ngữ trực quan nhân quả của PaliGemma. Mô hình ngôn ngữ thị giác nhân quả dự đoán mã thông báo tiếp theo dựa trên các mã thông báo trước đó. Keras Hub cung cấp các cách triển khai của nhiều cấu trúc mô hình phổ biến.
Tạo mô hình bằng phương thức from_preset và in bản tóm tắt của mô hình. Quá trình này sẽ mất khoảng một phút để hoàn tất.
paligemma = keras_hub.models.PaliGemmaCausalLM.from_preset("kaggle://keras/paligemma2/keras/pali_gemma2_mix_3b_224")
paligemma.summary()
Tạo các phương thức tiện ích
Để giúp bạn tạo phản hồi từ mô hình, hãy tạo 2 phương thức tiện ích:
crop_and_resize: Phương thức trợ giúp choread_img. Phương thức này cắt và đổi kích thước hình ảnh thành kích thước được truyền vào để hình ảnh cuối cùng được đổi kích thước mà không làm sai lệch tỷ lệ của hình ảnh.read_img: Phương thức trợ giúp choread_img_from_url. Phương thức này thực sự mở hình ảnh, đổi kích thước để phù hợp với các ràng buộc của mô hình và đặt hình ảnh đó vào một mảng mà mô hình có thể diễn giải.read_img_from_url: Nhận một hình ảnh thông qua một URL hợp lệ. Bạn cần phương thức này để truyền hình ảnh đến mô hình.
Bạn sẽ sử dụng read_img_from_url trong bước tiếp theo của sổ tay này.
def crop_and_resize(image, target_size):
width, height = image.size
source_size = min(image.size)
left = width // 2 - source_size // 2
top = height // 2 - source_size // 2
right, bottom = left + source_size, top + source_size
return image.resize(target_size, box=(left, top, right, bottom))
def read_image(url, target_size):
contents = io.BytesIO(requests.get(url).content)
image = PIL.Image.open(contents)
image = crop_and_resize(image, target_size)
image = np.array(image)
# Remove alpha channel if necessary.
if image.shape[2] == 4:
image = image[:, :, :3]
return image
def parse_bbox_and_labels(detokenized_output: str):
matches = re.finditer(
'<loc(?P<y0>\d\d\d\d)><loc(?P<x0>\d\d\d\d)><loc(?P<y1>\d\d\d\d)><loc(?P<x1>\d\d\d\d)>'
' (?P<label>.+?)( ;|$)',
detokenized_output,
)
labels, boxes = [], []
fmt = lambda x: float(x) / 1024.0
for m in matches:
d = m.groupdict()
boxes.append([fmt(d['y0']), fmt(d['x0']), fmt(d['y1']), fmt(d['x1'])])
labels.append(d['label'])
return np.array(boxes), np.array(labels)
def display_boxes(image, boxes, labels, target_image_size):
h, l = target_size
fig, ax = plt.subplots()
ax.imshow(image)
for i in range(boxes.shape[0]):
y, x, y2, x2 = (boxes[i]*h)
width = x2 - x
height = y2 - y
# Create a Rectangle patch
rect = patches.Rectangle((x, y),
width,
height,
linewidth=1,
edgecolor='r',
facecolor='none')
# Add label
plt.text(x, y, labels[i], color='red', fontsize=12)
# Add the patch to the Axes
ax.add_patch(rect)
plt.show()
def display_segment_output(image, bounding_box, segment_mask, target_image_size):
# Initialize a full mask with the target size
full_mask = np.zeros(target_image_size, dtype=np.uint8)
target_width, target_height = target_image_size
for bbox, mask in zip(bounding_box, segment_mask):
y1, x1, y2, x2 = bbox
x1 = int(x1 * target_width)
y1 = int(y1 * target_height)
x2 = int(x2 * target_width)
y2 = int(y2 * target_height)
# Ensure mask is 2D before converting to Image
if mask.ndim == 3:
mask = mask.squeeze(axis=-1)
mask = Image.fromarray(mask)
mask = mask.resize((x2 - x1, y2 - y1), resample=Image.NEAREST)
mask = np.array(mask)
binary_mask = (mask > 0.5).astype(np.uint8)
# Place the binary mask onto the full mask
full_mask[y1:y2, x1:x2] = np.maximum(full_mask[y1:y2, x1:x2], binary_mask)
cmap = plt.get_cmap('jet')
colored_mask = cmap(full_mask / 1.0)
colored_mask = (colored_mask[:, :, :3] * 255).astype(np.uint8)
if isinstance(image, Image.Image):
image = np.array(image)
blended_image = image.copy()
mask_indices = full_mask > 0
alpha = 0.5
for c in range(3):
blended_image[:, :, c] = np.where(mask_indices,
(1 - alpha) * image[:, :, c] + alpha * colored_mask[:, :, c],
image[:, :, c])
fig, ax = plt.subplots()
ax.imshow(blended_image)
plt.show()
Tạo đầu ra
Sau khi tải mô hình và tạo các phương thức tiện ích, bạn có thể nhắc mô hình bằng dữ liệu hình ảnh và văn bản để tạo câu trả lời. Các mô hình PaliGemma được huấn luyện bằng cú pháp câu lệnh cụ thể cho các tác vụ cụ thể, chẳng hạn như answer, caption và detect. Để biết thêm thông tin về cú pháp của nhiệm vụ trong câu lệnh PaliGemma, hãy xem bài viết Câu lệnh và hướng dẫn hệ thống của PaliGemma.
Chuẩn bị hình ảnh để sử dụng trong câu lệnh tạo bằng cách dùng mã sau để tải hình ảnh kiểm thử vào một đối tượng:
target_size = (224, 224)
image_url = 'https://storage.googleapis.com/keras-cv/models/paligemma/cow_beach_1.png'
cow_image = read_image(image_url, target_size)
matplotlib.pyplot.imshow(cow_image)
Trả lời bằng một ngôn ngữ cụ thể
Đoạn mã ví dụ sau đây cho thấy cách nhắc mô hình PaliGemma cung cấp thông tin về một đối tượng xuất hiện trong hình ảnh được cung cấp. Ví dụ này sử dụng cú pháp answer {lang} và cho thấy các câu hỏi khác bằng những ngôn ngữ khác:
prompt = 'answer en where is the cow standing?\n'
# prompt = 'svar no hvor står kuen?\n'
# prompt = 'answer fr quelle couleur est le ciel?\n'
# prompt = 'responda pt qual a cor do animal?\n'
output = paligemma.generate(
inputs={
"images": cow_image,
"prompts": prompt,
}
)
print(output)
Sử dụng lời nhắc detect
Đoạn mã ví dụ sau đây sử dụng cú pháp câu lệnh detect để xác định vị trí của một đối tượng trong hình ảnh được cung cấp. Đoạn mã này sử dụng các hàm parse_bbox_and_labels() và display_boxes() đã xác định trước đó để diễn giải đầu ra của mô hình và hiển thị các khung hình chữ nhật được tạo.
prompt = 'detect cow\n'
output = paligemma.generate(
inputs={
"images": cow_image,
"prompts": prompt,
}
)
boxes, labels = parse_bbox_and_labels(output)
display_boxes(cow_image, boxes, labels, target_size)
Sử dụng lời nhắc segment
Đoạn mã ví dụ sau đây sử dụng cú pháp câu lệnh segment để xác định vị trí của một đối tượng trong hình ảnh. Thư viện này sử dụng thư viện big_vision của Google để diễn giải đầu ra của mô hình và tạo một mặt nạ cho đối tượng được phân đoạn.
Trước khi bắt đầu, hãy cài đặt thư viện big_vision và các phần phụ thuộc của thư viện này, như minh hoạ trong ví dụ về mã này:
import os
import sys
# TPUs with
if "COLAB_TPU_ADDR" in os.environ:
raise "It seems you are using Colab with remote TPUs which is not supported."
# Fetch big_vision repository if python doesn't know about it and install
# dependencies needed for this notebook.
if not os.path.exists("big_vision_repo"):
!git clone --quiet --branch=main --depth=1 \
https://github.com/google-research/big_vision big_vision_repo
# Append big_vision code to python import path
if "big_vision_repo" not in sys.path:
sys.path.append("big_vision_repo")
# Install missing dependencies. Assume jax~=0.4.25 with GPU available.
!pip3 install -q "overrides" "ml_collections" "einops~=0.7" "sentencepiece"
Đối với ví dụ phân đoạn này, hãy tải và chuẩn bị một hình ảnh khác có chứa một con mèo.
cat = read_image('https://big-vision-paligemma.hf.space/file=examples/barsik.jpg', target_size)
matplotlib.pyplot.imshow(cat)
Sau đây là một hàm giúp phân tích cú pháp đầu ra phân đoạn từ PaliGemma
import big_vision.evaluators.proj.paligemma.transfers.segmentation as segeval
reconstruct_masks = segeval.get_reconstruct_masks('oi')
def parse_segments(detokenized_output: str) -> tuple[np.ndarray, np.ndarray]:
matches = re.finditer(
'<loc(?P<y0>\d\d\d\d)><loc(?P<x0>\d\d\d\d)><loc(?P<y1>\d\d\d\d)><loc(?P<x1>\d\d\d\d)>'
+ ''.join(f'<seg(?P<s{i}>\d\d\d)>' for i in range(16)),
detokenized_output,
)
boxes, segs = [], []
fmt_box = lambda x: float(x) / 1024.0
for m in matches:
d = m.groupdict()
boxes.append([fmt_box(d['y0']), fmt_box(d['x0']), fmt_box(d['y1']), fmt_box(d['x1'])])
segs.append([int(d[f's{i}']) for i in range(16)])
return np.array(boxes), np.array(reconstruct_masks(np.array(segs)))
Truy vấn PaliGemma để phân đoạn con mèo trong hình ảnh
prompt = 'segment cat\n'
output = paligemma.generate(
inputs={
"images": cat,
"prompts": prompt,
}
)
Hình dung mặt nạ được tạo từ PaliGemma
bboxes, seg_masks = parse_segments(output)
display_segment_output(cat, bboxes, seg_masks, target_size)
Câu lệnh theo lô
Bạn có thể cung cấp nhiều lệnh trong một câu lệnh duy nhất dưới dạng một nhóm chỉ dẫn. Ví dụ sau đây minh hoạ cách cấu trúc văn bản câu lệnh để cung cấp nhiều chỉ dẫn.
prompts = [
'answer en where is the cow standing?\n',
'answer en what color is the cow?\n',
'describe en\n',
'detect cow\n',
'segment cow\n',
]
images = [cow_image, cow_image, cow_image, cow_image, cow_image]
outputs = paligemma.generate(
inputs={
"images": images,
"prompts": prompts,
}
)
for output in outputs:
print(output)
Chạy trong Google Colab
Xem nguồn trên GitHub