> ## Content Index
> Fetch the complete content index at: https://www.hubwiz.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# 基于语义搜索假装图像生成
- URL: https://www.hubwiz.com/blog/fake-image-generation-using-semantic-search/
- Published: 2026-04-18T15:58:06.000Z
- Updated: 2026-04-18T15:58:06.000Z
- Description: 如何使用现有的图片数据集来模拟图像生成过程并获得灵感。
- Author: admin
- Tags: APPLICATION, #Import 2026-10-14 14:41

经过一个月的休息，我回来了。我一直在刚果完成一个石油天然气项目。在这段休息时间里，我有了一些想法，现在我有时间把它们写下来分享给大家。

在这篇文章中，我将继续之前开始的内容。

我将向你展示如何调整一个已发布的现有项目。

> 它叫做 ***Fake Image Generation***（伪造图像生成）

这个名字可能会产生误导：我们并不是在创建伪造的图像……我们是在模拟图像生成过程，而不是真正地进行生成！

我是一个PoorGPUguy，所以图像生成是可行的，**但生成一张1024x640像素的图片大约需要30分钟**。

但是，如果我们能使用一个足够大的图像数据集，然后在我们期望的提示词和现有提示词（来自图像数据集）之间使用余弦相似度搜索呢？

我们将获得许多与我们需求足够接近的结果！同时，我们还可以从新的提示词（它们的风格、颜色、构图、相机角度）中获得一些灵感。

如果你感兴趣……让我们继续吧！

### 1、前提条件

阅读我之前的文章（这里没有付费墙）：

[Fake Image Generator Model — part 1](https://medium.com/artificial-intel-ligence-playground/fake-image-generator-model-part-1-14f1036d808e?ref=hubwiz.com) — 如何使用数据集来模拟图像生成并获得灵感。

[Fake image generator model — part 2](https://medium.com/artificial-intel-ligence-playground/fake-image-generator-model-part-2-decd7d2c26f9?ref=hubwiz.com) — 图书管理员和表演者：AI搜索如何假装魔术。从相似度搜索到图像检索。

阅读并测试之后……回到这里。

我将向你展示如何使用不同的图像数据集（来自[HuggingFace](https://huggingface.co/?ref=hubwiz.com)）并做同样的事情。

下周我们将介绍合并初始的[kaupane/nano-banana-pro-gen](https://huggingface.co/datasets/kaupane/nano-banana-pro-gen?ref=hubwiz.com)和今天博文中的新数据集[open-image-preferences-v1-binarized](https://huggingface.co/datasets/cerealt/open-image-preferences-v1-binarized?ref=hubwiz.com)的过程。

![None](https://www.hubwiz.com/blog/content/images/2026/04/1-Q5-ZeWNJBo747hrdnJazfQ.png)

这是我的硬件配置……不是很好对吧？

> **注意：我在一台旧的Lenovo X260上测试所有项目，Intel Core i5，16GB内存。如果我能做到，你也能做到！**

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-P7pn3tF15o_QfcNj.jpeg)

## 1、准备工具

如果你已经跟进了Medium上的文章……你几乎已经拥有了所需的一切。如果你直接跳到这里，让我们回顾一下。

#### 1.1 Python虚拟环境

创建一个新的项目目录（我的叫FIG2）。在终端中打开它并创建一个新的虚拟环境

```
python -m venv venv

```

然后激活它：

```
# in powershell
.\venv\Scripts\activate

# in CMD
venv\Scripts\activate.bat

```

现在我们需要安装一些Python包：我已经移除了对重型包（如torch）的需求，因为我们将使用`numpy`来计算余弦相似度，而不是`sentence-transformers`库。

```
pip install datasets requests tqdm huggingface_hub ipython pandas pyarrow gradio numpy faiss-cpu

```

注意这次我添加了`ipython`：我们将使用这个有用的交互式Python shell在步骤1中探索数据集。

接下来是llama.cpp二进制文件：我们使用**llama-server**来托管我们将通过`requests`库调用的嵌入端点。嵌入模型是一样的：[BAAI/bge-m3](https://huggingface.co/BAAI/bge-m3?ref=hubwiz.com)，它是完美的、轻量级的，而且支持多语言。

在同一个主目录中下载llama.cpp的ZIP存档，然后在那里解压。

- [下载llama.cpp二进制文件](https://github.com/ggml-org/llama.cpp/releases/download/b8779/llama-b8779-bin-win-cpu-x64.zip?ref=hubwiz.com)

在同一个目录中下载嵌入模型的GGUF（量化权重）文件。

- [下载bge-m3-q8\_0.gguf](https://huggingface.co/ggml-org/bge-m3-Q8%5F0-GGUF/resolve/main/bge-m3-q8%5F0.gguf?download=true&ref=hubwiz.com)

一切就绪。

额外建议：还可以下载一个模型来帮助你调整现有项目，使其适应新的数据集。我建议下载[Qwen\_Qwen3.5–2B-Q5\_K\_L.gguf](https://huggingface.co/bartowski/Qwen%5FQwen3.5-2B-GGUF/blob/main/Qwen%5FQwen3.5-2B-Q5%5FK%5FL.gguf?ref=hubwiz.com)。这是最新的Qwen 3.5模型，20亿参数，在CPU上运行速度快，同时几乎保持与原始模型相同的精度。

[Qwen\_Qwen3.5–2B-Q5\_K\_L.gguf](https://huggingface.co/bartowski/Qwen%5FQwen3.5-2B-GGUF/resolve/main/Qwen%5FQwen3.5-2B-Q5%5FK%5FL.gguf?download=true&ref=hubwiz.com)

这个模型是Qwen的推理/非推理模型，以小格式打包了惊人的能力！

稍后我将向你展示如何将其用作编程助手。

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-gGYT4iCOYbM7zMPh.png)

图片来自[HF仓库](https://huggingface.co/datasets/cerealt/open-image-preferences-v1-binarized?ref=hubwiz.com)

## 3、探索数据集

这是必不可少的部分。

并非所有数据集都是一样的。不同仓库之间的表头和记录可能会有很大差异。

你可以在Hugging Face上通过模态 = image来筛选数据集进行探索：

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-KjRpYVAnpSYQuPvB.png)

链接在[这里](https://huggingface.co/datasets?modality=modality:image&sort=created&ref=hubwiz.com)

浏览了一页又一页之后，我找到了[open-image-preferences-v1-binarized](https://huggingface.co/datasets/cerealt/open-image-preferences-v1-binarized?ref=hubwiz.com)。

```
- Goal: This project aims to create 10K text-to-image preference pairs. 
These pairs can be used to evaluate the performance of image generation models across 
a wide variety of common image categories, based on prompt with varying levels of difficulty.
- How: We use the prompts from fal/imgsys-results, these prompts are evolved based on 
complexity and quality for various image categories. We then asked the community to 
annotate the preference between two generated images for each prompt.
 - Result: We achieved to annotate 10K preference pairs.

```

尽管数据集的目标与我们的目标不一致……我们仍然获得了数千张生成的图像（来自不同的模型）及其初始提示词。

而这正是我们需要的！

要查看仓库的结构，你可以：

- 在Hugging Face上探索数据集
- 下载一个小样本到本地以了解如何使用

我们将选择方案2，使用`ipython`。

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-J487VOd4oC1Jk3HN.png)

在终端中，激活`venv`后，运行：

```
ipython

```

Ipython是一个令人惊叹的交互式shell。你可以按单元格运行代码（如果你听说过Google Colab Notebooks或Jupyter Notebook……它们都来自ipython）。好处是每个单元格可以多次运行或修改。如果你打错了什么，不必从头运行整个Python程序。跟着我来：

![](https://www.hubwiz.com/blog/content/images/2026/04/image-275.png)

你可以在[这里免费获取iPython速查表](https://build-your-own-ai.kit.com/ipythoncheatsheet?ref=hubwiz.com)

回到探索：我们将使用文章第一部分中相同的代码：

```
from datasets import load_dataset
import pandas as pd
from PIL import Image
import io

# Load just a small sample
def explore_sample_streaming(dataset_name, split_name="train", num_samples=100):
    """Stream a small sample of the dataset"""
    print(f"Loading {num_samples} samples from {dataset_name}...")
    # Use streaming to avoid downloading everything
    dataset = load_dataset(dataset_name, split=split_name, streaming=True)
    # Take a small sample
    sample_data = []
    for i, example in enumerate(dataset.take(num_samples)):
        sample_data.append(example)
        if i % 10 == 0:
            print(f"Loaded {i+1} samples...")
    # Convert to DataFrame for exploration
    df = pd.DataFrame(sample_data)
    print(f"\nDataset Schema:")
    print(f"Columns: {list(df.columns)}")
    print(f"Sample size: {len(df)}")
    print("\nFirst few rows:")
    print(df.head())
    return df
# Use it
repo = input("Paste the repo name: ") #e.g. cerealt/open-image-preferences-v1-binarized
samples = input("Num of samples: ")
num_sample = int(samples) #ex 50
sample_df = explore_sample_streaming(repo, num_samples=num_sample)

```

将此代码粘贴到ipython中，当被要求输入仓库名称时，使用新的：`cerealt/open-image-preferences-v1-binarized`

在这个例子中我只放了10个样本：结果需要理解……

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-W-eCB6FaDL8SEx0G.png)

我们可以看到一个叫做prompt的字段，这很好。但是图像呢？

在在线仓库中，它们在`chosen`和`rejected`字段中。

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-ZR9WQ-AxZajvm4kT.png)

让我们探索这些字段，了解它们是什么数据类型（字符串、URL还是PIL图像对象）：

```
first_sample = sample_df.iloc[1]
first_sample

```

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-WB8ytZhXUjQoUmeN.png)

看起来chosen/rejected是字节对象（文件）。让我们看看是否可以用Pillow加载它们。

```
image_data = first_sample['chosen']['bytes']
image = Image.open(io.BytesIO(image_data))
image.show()

```

你应该会看到爱丽丝梦游仙境的图像 😂

> *注意：顺便说一句，被拒绝的图像也可以显示*

```
image_data1 = first_sample['chosen']['bytes']
image_data2 = first_sample['rejected']['bytes']
image1 = Image.open(io.BytesIO(image_data1))
image2 = Image.open(io.BytesIO(image_data2))
image1.show()
image2.show()

```

![](https://www.hubwiz.com/blog/content/images/2026/04/image-276.png)

现在我们知道：

- **提示词**在`prompt`字段中
- **图像**在`chosen`字段中，它是一个可以用Pillow加载的字节对象

我们现在可以继续从仓库下载`.parquet`文件了。

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-NA3dnAdjNi_-RLC8.png)

文件在Files and versions标签下的data子文件夹中

## 4、下载图像和提示词

在这里，我们要构建我们的`json`数据库，包含新图像，准备好在本地计算机上使用。

在我这个项目的原始仓库中，我有一个脚本来完成这个任务。但那个Python应用程序是为初始的[kaupane/nano-banana-pro-gen](https://huggingface.co/datasets/kaupane/nano-banana-pro-gen?ref=hubwiz.com)数据集量身定制的。

你可以在我的GitHub仓库中找到原始文件

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-_jBQYbKJiPMz4yVf.png)

[https://github.com/fabiomatricardi/Fake-Image-Generator](https://github.com/fabiomatricardi/Fake-Image-Generator?ref=hubwiz.com)

如何修复它？

让我们看看原始文件[1.big\_dset\_parquet\_Ask.py](https://github.com/fabiomatricardi/Fake-Image-Generator/blob/main/1.big%5Fdset%5Fparquet%5FAsk.py?ref=hubwiz.com)，找出需要修改的地方。

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-TDJwhHyLCq08zKbu.png)

到第164行，我们有了下载数据集的辅助函数。我们需要在主脚本中找到，我们读取统一parquet文件并提取提示词和图像的位置。

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-fTvyip30snipf0Av.png)

在第271行，我们从统一的parquet文件加载数据集：我们要找的就是那之后的部分！

在第320行，我们找到了关键位置：

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-cNGBDLm7pHn9CoTf.png)

我们之前已经测试了如何访问图像：它不在一个叫做'image'的字段中。我们还知道这是一个字节对象，而不是PIL实例（就像原始数据集中那样）。

让我们结合我们的知识来修复这个问题：

```
try:
    # Save image for new dataset cerealt/open-image-preferences-v1-binarized
    ########################################################################
    if 'chosen' in example and example['chosen']['bytes'] is not None:
        image_data1 = example['chosen']['bytes']
        image1 = Image.open(io.BytesIO(image_data1))
        image1.save(full_path)

        # Get prompt
        prompt = example.get('prompt', '')
        if not prompt and 'json' in example and isinstance(example['json'], dict):
            prompt = example['json'].get('prompt') or example['json'].get('caption') or str(example['json'])

```

我们验证`chosen`字段存在且`bytes`对象不为空：然后我们使用与之前完全相同的代码来读取字节流并保存它。

> **注意：在我们的原始文件中，io库没有被导入。记得在顶部添加导入**

![None](https://www.hubwiz.com/blog/content/images/2026/04/0--WpYTIloOY5HRqAK.png)

## 5、更改编号策略

如果我们按原样运行代码，即使做了这些小修改，我们也会遇到另一个问题：新图像将从0开始编号。

但我们已经有了这些数字（至少在nano-banana数据集中有）：如果将来我们想把图像合并到一个文件夹中怎么办？

许多图像将被覆盖。

我们需要添加一个增量，一个不同的起始点，这样不同的`json`索引在合并时不会冲突。

我是这样做的：

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-PITb7VmaWXFZn8Ag.png)

我们可以创建一个从2000开始的起始点（我们的原始数据集大约有1k张图像，所以我们可以避免重叠）。

```
mydelta = 2000

```

然后我们将`mydelta`数字添加到所有相关项目：

- 图像`filename`\* 最终JSON文件中的`ID`
- 最终JSON文件中的`index`

> 有了这些小技巧，我们可以在将来（下周）合并不同的`.json`索引时使用新的数据集。

我们将借助AI助手的帮助来完成（我真的不知道如何自己做）

如果你迷路了或代码在某处出错，我把新文件命名为`11.new_dataset.py`，你可以从我的GitHub仓库下载

- [下载11.new\_dataset.py](https://github.com/fabiomatricardi/Fake-Image-Generator/raw/main/11.new%5Fdataset.py?ref=hubwiz.com)

让我们运行新的Python应用程序，指向新仓库`cerealt/open-image-preferences-v1-binarized`

在终端中，激活venv后，运行

```
python .\11.new_dataset.py

```

这是我的运行结果

## 6、测试生成模拟

下一步是验证生成模拟。按照文章第一部分，我们将使用一个随机函数（使用我们新的范围……）。

我把新的Python Gradio应用命名为**12.FAKE\_Image\_Generator.py**：你需要调整的原始文件是[2.FAKE\_Image\_Generator.py](https://github.com/fabiomatricardi/Fake-Image-Generator/blob/main/2.FAKE%5FImage%5FGenerator.py?ref=hubwiz.com)

我们的图像（如果你按照视频中的相同设置）从2800开始，到3699结束。

让我们调整代码：从原始文件来看，修改非常直观

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-tgmxxCKvbMgli0ff.png)

在第21行，我们需要将`randint`函数的起始/终止改为类似这样：

```
# Open the image file
    random_int = random.randint(2800, 3699) # Random int between 2800 and 3699

```

保存文件，然后在终端中激活`venv`后运行：

```
gradio .\12.FAKE_Image_Generator.py

```

![](https://www.hubwiz.com/blog/content/images/2026/04/image-277.png)

## 7、结束语

希望到目前为止你喜欢这些内容。

调整现有的应用很酷，因为你需要理解代码以及在哪里修改它。

有时候AI生成代码的最大问题……是你根本不知道那里发生了什么。如果你不得不亲自动手修复它，那就变成了一项**不可能完成的任务**。

下次我们将调整最终应用并为新数据集生成**FAISS数据库**。

接下来，如何合并现有图像和`json`索引以增加我们伪造生成的样本量。

---

原文链接: [Image generation without Generation: the power of semantic search — part 3](https://medium.com/artificial-intel-ligence-playground/image-generation-without-generation-the-power-of-semantic-search-part-3-83048352448a?ref=hubwiz.com)

汇智网翻译整理，转载请标明出处