You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

处理30万条记录的CSV时Embedding进程卡顿,求优化方案

优化大数量级Embedding生成脚本的方案

核心误解纠正

OpenAI的Embedding.create接口完全支持批量输入,一次可传入多个文本(只要总token数不超过模型限制,text-embedding-ada-002单请求最大支持8191token),这是解决30万条数据处理缓慢的关键。


优化方案与代码示例

1. 批量调用API(最有效提速手段)

替换逐行apply为批量请求,大幅减少API调用次数:

import os
import pandas as pd
import openai
from dotenv import load_dotenv

load_dotenv('.env')
openai.api_key = os.getenv('OPENAI_API_KEY')

def get_batch_embeddings(texts, model="text-embedding-ada-002"):
    response = openai.Embedding.create(input=texts, model=model)
    return [item['embedding'] for item in response['data']]

# 加载数据
dataset = pd.read_csv('keywords.csv', encoding='ISO-8859-1')

# 分批次处理(根据文本长度调整batch_size,确保总token不超限)
batch_size = 1000
embeddings = []
for i in range(0, len(dataset), batch_size):
    batch_texts = dataset['keyword'].iloc[i:i+batch_size].tolist()
    batch_embeds = get_batch_embeddings(batch_texts)
    embeddings.extend(batch_embeds)
    print(f"已处理 {i+len(batch_embeds)} / {len(dataset)} 条数据")

# 赋值并保存(用parquet格式存储数组类型更高效)
dataset['embedding'] = embeddings
dataset.to_parquet('keywords_with_embeddings.parquet')

# 查询逻辑
keyword = input('Input:')
keyword_vector = get_batch_embeddings([keyword])[0]
print(keyword_vector)

2. 异步并发请求(进一步提升效率)

使用OpenAI异步客户端并发处理多个批次,充分利用带宽:

import asyncio
from openai import AsyncOpenAI

client = AsyncOpenAI(api_key=os.getenv('OPENAI_API_KEY'))

async def get_async_batch_embeddings(texts, model="text-embedding-ada-002"):
    response = await client.embeddings.create(input=texts, model=model)
    return [item.embedding for item in response.data]

async def process_batches_async(dataset, batch_size=1000):
    tasks = []
    for i in range(0, len(dataset), batch_size):
        batch_texts = dataset['keyword'].iloc[i:i+batch_size].tolist()
        tasks.append(get_async_batch_embeddings(batch_texts))
    all_embeddings = await asyncio.gather(*tasks)
    return [embed for batch in all_embeddings for embed in batch]

# 执行异步处理
embeddings = asyncio.run(process_batches_async(dataset))
dataset['embedding'] = embeddings
dataset.to_parquet('keywords_with_embeddings.parquet')

3. 增量处理与缓存(避免重复生成)

将已生成的embedding持久化,后续仅处理新增数据:

try:
    # 加载已有数据
    existing_dataset = pd.read_parquet('keywords_with_embeddings.parquet')
    # 筛选未处理的关键词
    new_dataset = dataset[~dataset['keyword'].isin(existing_dataset['keyword'])]
    print(f"已有 {len(existing_dataset)} 条数据,新增 {len(new_dataset)} 条待处理")
    
    if len(new_dataset) > 0:
        new_embeddings = get_batch_embeddings(new_dataset['keyword'].tolist())
        new_dataset['embedding'] = new_embeddings
        dataset = pd.concat([existing_dataset, new_dataset], ignore_index=True)
    else:
        dataset = existing_dataset
except FileNotFoundError:
    # 首次处理全量数据
    embeddings = get_batch_embeddings(dataset['keyword'].tolist())
    dataset['embedding'] = embeddings

dataset.to_parquet('keywords_with_embeddings.parquet')

4. 处理速率限制(避免限流中断)

加入重试机制,应对OpenAI的API速率限制:

import time

def get_batch_embeddings_with_retry(texts, model="text-embedding-ada-002"):
    while True:
        try:
            response = openai.Embedding.create(input=texts, model=model)
            return [item['embedding'] for item in response['data']]
        except openai.RateLimitError:
            print("触发速率限制,等待10秒后重试...")
            time.sleep(10)

内容的提问来源于stack exchange,提问作者tbo812

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:45:07