使用Sentence Transformers处理5万张图片嵌入时遇‘打开文件过多’问题求助
解决Sentence Transformers提取图片Embedding时的“too many open files”错误
错误原因
你的代码通过列表推导式一次性打开了所有50000张图片,这会同时占用大量文件描述符,超出系统允许的最大打开文件数限制,从而触发too many open files错误。
解决方案
1. 分批读取并处理图片(最可靠方案)
不要一次性打开所有图片,分批次读取、编码,每处理完一批就释放对应文件资源。示例代码如下:
from sentence_transformers import SentenceTransformer, util from PIL import Image # 加载CLIP模型 model = SentenceTransformer('clip-ViT-B-32') # 设置每批处理的图片数量(可根据系统资源调整,如128或256) batch_size = 128 img_embs = [] # 分批处理图片 for i in range(0, len(image_names), batch_size): batch_files = image_names[i:i+batch_size] batch_imgs = [] # 用with上下文管理器确保图片及时关闭 for filepath in batch_files: with Image.open(filepath) as img: # 复制图片对象,避免with块结束后资源被释放 batch_imgs.append(img.copy()) # 编码当前批次图片 batch_emb = model.encode(batch_imgs, convert_to_tensor=True) img_embs.append(batch_emb) # 手动清理当前批次的图片对象,加速资源回收 del batch_imgs # 合并所有批次的embedding img_emb = util.concatenate(img_embs, axis=0)
2. 临时调整系统最大打开文件数(辅助方案)
如果分批处理后仍有问题,可以临时提高系统的文件描述符限制:
- Linux/macOS:终端执行
ulimit -n 65535(临时生效,重启后恢复),或修改系统配置文件永久调整。 - Windows:通过组策略或注册表修改
HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters下的MaxOpenFiles值(需重启生效)。
此方案仅为缓解手段,不如分批处理从根源解决问题——即使提高限制,一次性打开5万个文件仍会占用大量系统资源。
3. 优化资源回收逻辑
处理完每批图片后,手动删除对应的图片对象(如示例中的del batch_imgs),触发Python垃圾回收,及时释放文件描述符。
关键注意点
- 不要长期持有大量Image对象,避免持续占用文件描述符。
- 调整
batch_size时,需结合自身系统的内存和文件描述符限制,避免过大导致内存不足。
内容的提问来源于stack exchange,提问作者Vadim
相关产品推荐
相关产品推荐

