☰
FlexGen 应用实战:文本补全、数据清洗与 HELM 评测三场景详解
2026/9/25 5:28:31 网站建设 项目流程
  • 推理引擎
  • 大模型

【免费下载链接】FlexGen

Running large language models on a single GPU for throughput-oriented scenarios.

项目地址:https://gitcode.com/gh_mirrors/fl/FlexGen
点击查看免费下载

本文基于 FlexGen 仓库中flexgen/apps/目录下的应用文档与配套源码,系统讲解如何在单 GPU 上利用 FlexGen 运行 OPT 系列大模型,完成三类典型任务:交互式文本补全(Completion)、数据清洗(Data Wrangling,含实体匹配、数据补全与错误检测)以及 HELM 大规模评测基准(如 MMLU 场景)。读完本文,你将掌握三个可运行的入口脚本(completion.py、data_wrangle_run.py、helm_run.py)的完整命令行参数、FlexGen 六元组 offload 策略(--percent)的配置方法,以及如何在 16GB 显存等受限硬件上跑通 6.7B/30B/175B 级模型并解读其吞吐数据。

一、apps 目录与核心概念速览

flexgen/apps/是 FlexGen 面向实际应用场景提供的开箱即用示例集合,目录结构如下:

  • flexgen/apps/completion.py:单机文本补全入口,演示用 OPT 模型完成句子;
  • flexgen/apps/helm_run.py:HELM 评测场景执行器,可跑 MMLU、WikiFact、XSUM 等大规模评测;
  • flexgen/apps/data_wrangle/:数据清洗任务(实体匹配 EM、数据补全 DI、错误检测 ED)的完整实现与基准脚本;
  • flexgen/apps/helm_fast_test.py 与 flexgen/apps/helm_passed_30b.sh:HELM 场景清单与批量跑测脚本。

在深入各场景前,必须先理解 FlexGen 的核心编程模型,这些概念在三个入口脚本中被反复使用,均来自 flexgen/flex_opt.py:

  • ExecutionEnv:执行环境,通过ExecutionEnv.create(offload_dir)创建,负责管理 CPU/GPU/NVMe SSD 之间的张量搬运线程;脚本结束后需调用env.close_copy_threads()关闭拷贝线程(见 completion.py)。
  • OptLM:OPT 模型封装,OptLM(model_name, env, path, policy)加载模型;--path指向权重缓存目录(~/opt_weights),若没有缓存权重,FlexGen 会自动从 HuggingFace 下载。
  • Policy:offload 策略对象,其核心字段是六元组百分比percent,在 flex_opt.py 中定义为权重在 GPU/CPU、注意力缓存(KV cache)在 GPU/CPU、激活值在 GPU/CPU 的占比;剩余比例(100 - w_gpu - w_cpu)自动落到 NVMe 磁盘(w_disk_percent,见 flex_opt.py)。
  • 量化压缩:--compress-weight/--compress-cache分别对权重和 KV 缓存做分组量化,默认配置为 4-bit、group_size=64(权重按group_dim=0分组、缓存按group_dim=2分组,非对称量化),可在 completion.py 与 helm_run.py 中看到一致的构造方式。

三个脚本都通过argparse暴露相同的一组 FlexGen 参数,这是本文所有命令的基础:

参数默认值含义
--modelfacebook/opt-6.7b(completion)/facebook/opt-1.3b(helm、data_wrangle)模型名
--path~/opt_weights权重路径,无缓存时自动下载
--offload-dir~/flexgen_offload_dir张量 offload 目录
--percent100 0 100 0 100 0六个数:权重 GPU%、权重 CPU%、缓存 GPU%、缓存 CPU%、激活 GPU%、激活 CPU%
--pin-weightTrue是否将 CPU 权重固定在(不可换页的)内存中
--cpu-cache-compute关闭是否在 CPU 上计算注意力缓存
--compress-weight关闭是否对权重做 4-bit 量化压缩
--compress-cache关闭是否对 KV 缓存做 4-bit 量化压缩
--gpu-batch-size16单轮 GPU batch 大小
--num-gpu-batches1GPU batch 批次数,二者乘积即有效批量

二、场景一:Completion 文本补全

flexgen/apps/README.md 给出的首个示例是文本补全:在一台拥有32GB 系统内存 + 24GB 显存的机器上直接跑 OPT-30B 与 OPT-66B:

python completion.py --model facebook/opt-30b --percent 100 0 100 0 100 0 --compress-weight python completion.py --model facebook/opt-66b --percent 50 10 100 0 100 0 --compress-weight

两个命令的差异恰好演示了 offload 策略的调整思路:

  • OPT-30B(约 60GB 权重):显存足够时优先使用100 0 100 0 100 0,即权重、缓存、激活全部放 GPU,配合--compress-weight将权重压到 4-bit,进一步降低显存占用;
  • OPT-66B(约 132GB 权重):单卡显存已不足以全量放权重,因此改用50 10 100 0 100 0——50% 权重放 GPU、10% 放 CPU、剩余 40% 由 FlexGen 自动 offload 到 NVMe 磁盘,同时保持缓存与激活 100% 在 GPU 上,保证推理吞吐。

从 completion.py 源码可以看到,脚本内置了两组 QA 风格的示例 prompt(如"2004 年奥运会在哪里举办?""从文本中抽取机场代码"),并做了以下配置:

  • 使用AutoTokenizer.from_pretrained("facebook/opt-30b", padding_side="left")加载左填充分词器,关闭 BOS token(tokenizer.add_bos_token = False);
  • 以换行符\n的 token id 作为生成停止符(stop = tokenizer("\n").input_ids[0]);
  • 将 prompt 统一 padding 到 128 长度后调用model.generate(input_ids, do_sample=True, temperature=0.7, max_new_tokens=32, stop=stop)(见 completion.py)。

运行后脚本会打印首尾两条生成结果与分隔线,最后调用env.close_copy_threads()优雅关闭 offload 线程。该脚本是最轻量的 FlexGen 上手路径:改--model即可在不同规模的 OPT 模型间切换,--percent则负责按你的显存/内存比例分配负载。

三、场景二:Data Wrangling 数据清洗任务

3.1 任务背景与安装

FlexGen 对数据清洗任务的支持实现了 HazyResearch 的 fm_data_tasks 项目思路,覆盖三类任务(详见 flexgen/apps/data_wrangle/README.md):

  • Entity Match(EM,实体匹配):判断两条记录是否指向同一实体,如 Fodors-Zagats、Beer、iTunes-Amazon、Walmart-Amazon、Amazon-Google、DBLP-ACM、DBLP-GoogleScholar 等 7 个数据集;
  • Data Imputation(DI,数据补全):根据已有字段补全缺失属性值,如 Restaurant(补 city)与 Buy(补 manufacturer);
  • Error Detection(ED,错误检测):发现数据中的拼写/取值错误,如 Hospital 数据集。

安装分两步(对应 install.sh):

cd data_wrangle bash install

脚本会安装pandas==1.4.2、sentence-transformers==2.2.2、rich==12.2.0、pyarrow==7.0.0等依赖,并创建data/目录、从fm-data-tasks的公开存储桶下载datasets.tar.gz后解压。数据集目录与任务的映射关系定义在 flexgen/apps/data_wrangle/utils/constants.py(如entity_matching/structured/Beer→entity_matching),各数据集要丢弃的列、补全列也集中在此文件中,便于按需定制。

3.2 单查询与批量查询两种运行模式

主程序 flexgen/apps/data_wrangle/data_wrangle_run.py 通过--batch_run标志切换两种模式(见 data_wrangle_run.py):

  • 单查询模式(single_query_test):逐条构造 prompt 并调用model.generate,用于验证结果正确性。仓库提供了快速验证脚本:
    • bash test_single_query_case.sh:验证 Restaurant 数据补全任务在 OPT-6.7B 上的输出;
    • bash test_single_query_all_opt6.7b.sh:对 OPT-6.7B 跑完所有任务的单条样例(prompt 统一 pad 到 32 长度)。
  • 批量查询模式(batch_query_test):一次性处理全部样本,同时记录总耗时与吞吐,用于测试 FlexGen 的吞吐性能:
    • bash test_batch_query_case.sh:验证 Restaurant 任务批量模式;
    • bash test_batch_query_all_opt6.7b.sh/test_batch_query_all_opt30b.sh/test_batch_query_all_opt175b.sh:分别在三种规模模型上跑完整测试集。

以 test_batch_query_all_opt6.7b.sh 中的实体匹配任务为例(Fodors-Zagats):

python3 ./data_wrangle_run.py \ --num_run 189 --num_trials 1 --nan_tok "" --do_test \ --sample_method manual \ --data_dir data/datasets/entity_matching/structured/Fodors-Zagats \ --batch_run --pad-to-seq-len 744 --model facebook/opt-6.7b \ --percent 100 0 100 0 100 0 --gpu-batch-size 2 --num-gpu-batches 1

OPT-6.7B 全部任务均采用100 0 100 0 100 0(全 GPU 策略);OPT-30B 脚本改用10 90 0 100 0 100(权重 10% GPU + 90% CPU,缓存与激活全 CPU,见 test_batch_query_all_opt30b.sh);OPT-175B 则使用--pin-weight 0 --percent 0 50 0 0 0 100(权重全放 CPU 并 offload 磁盘、激活全 CPU,见 test_batch_query_all_opt175b.sh),并通过增大--gpu-batch-size与--num-gpu-batches的乘积换取更高批量吞吐。

各任务差异参数一览(以 6.7B 脚本为例):

任务数据集--num_run--pad-to-seq-len--max_tokens--gpu-batch-size
EM: Fodors-Zagats1897443(默认)2
EM: Beer915923(默认)2
EM: iTunes-Amazon1095293(默认)2
EM: Walmart-Amazon2007483(默认)2
EM: Amazon-Google2008763(默认)1
EM: DBLP-ACM20012743(默认)1
EM: DBLP-GoogleScholar20012093(默认)1
DI: Restaurant8612358
DI: Buy65488102
ED: Hospital2002003(默认)5

从 data_wrangle_run.py 源码可见批量模式的内部逻辑:先逐条 tokenize 并记录max_prompt_seq_length,再统一 padding 后按flexgen_batch_size = gpu_batch_size * num_gpu_batches切分成多个 mini-batch 循环调用model.generate;吞吐按两个口径统计:output_throughput = num_run * max_tokens / total_time与total_throughput = (num_run * max_prompt_seq_length + num_run * max_tokens) / total_time(即输入 + 输出 token 合计)。每次 trial 结束后预测、查询、ground-truth 会以 feather 格式落盘,指标(Prec/Recall/Acc/F1 及其均值方差)写入metrics.json(见 data_wrangle_run.py)。

3.3 提示构造方式

提示词由 flexgen/apps/data_wrangle/utils/prompt_utils.py 负责构造,支持三种--sample_method(random/manual/validation_clusters,默认random):

  • manual:使用各数据集预定义的固定前缀模板(get_manual_prompt,见 prompt_utils.py);
  • random:从训练集中随机采样--k条带标签样例作为 few-shot 前缀(get_random_prompt);
  • validation_clusters:基于 sentence embedding 聚类挑选"难样本"作为提示(get_validation_prompt,使用sentence-transformers/sentence-t5-base)。

其余相关参数还包括--k(prompt 中示例条数,默认 1)、--sep_tok(属性-值对分隔符,默认.)、--nan_tok(缺失值记号,默认nan)、--temperature(默认 0.0)、--max_tokens(默认 3)、--stop_token(默认\n)以及--num_trials(重复试验次数,默认 1)等(见 data_wrangle_run.py)。

3.4 基准测试结果

flexgen/apps/data_wrangle/README.md 明确指出此类任务的特点:输入序列很长(123~1274 token),而输出很短(3/5/10 token),推理时间几乎全部消耗在 prefill 阶段,因此基准采用"输入 + 输出 token 合计"的吞吐口径。实验环境为:单张 T4(16GB)GPU、200GB DRAM、1.5TB NVMe SSD,与 HELM 基准采用相同设置。

OPT-6.7B 结果:

任务测试样本输入长度输出长度耗时 (s)输入+输出吞吐 (token/s)
EM: Fodors-Zagats1897443109.5561281.871
EM: Beer91592342.0871272.360
EM: iTunes-Amazon109529359.467966.178
EM: Walmart-Amazon2007483126.5381186.992
EM: Amazon-Google2008763144.5931215.828
EM: DBLP-ACM20012743207.5131230.767
EM: DBLP-GoogleScholar20012093232.651097.78
DI: Restaurant86123510.397984.865
DI: Buy654881043.077739.876
ED: Hospital200200330.1371347.203

OPT-30B 结果:

任务测试样本输入长度输出长度耗时 (s)输入+输出吞吐 (token/s)
EM: Fodors-Zagats1897443541.550248.287
EM: Beer915923238.58224.450
EM: iTunes-Amazon1095293267.639198.775
EM: Walmart-Amazon2007483682.635220.030
EM: Amazon-Google2008763799.514219.884
EM: DBLP-ACM200127431119.272228.184
EM: DBLP-GoogleScholar200120931271.534190.636
DI: Restaurant86123560.310169.790
DI: Buy6548810185.882160.747
ED: Hospital2002003158.329256.429

OPT-175B 结果:

任务测试样本输入长度输出长度耗时 (s)输入+输出吞吐 (token/s)
EM: Fodors-Zagats18974433928.31034.228
EM: Beer9159231356.78635.083
EM: iTunes-Amazon10952931569.06233.906
EM: Walmart-Amazon20074834171.31936.008
EM: Amazon-Google20087634893.57235.925
EM: DBLP-ACM200127437624.72633.496
EM: DBLP-GoogleScholar200120938275.82829.290
DI: Restaurant861235648.76216.968
DI: Buy65488102086.96114.317
ED: Hospital20020031154.13335.178

三组数据可以清晰看出:模型规模从 6.7B → 30B → 175B,吞吐量大致以约 5 倍、再约 6 倍的速度递减,但即便在单张 16GB T4 上,OPT-175B 也能以 30 token/s 左右的合计吞吐完成全部 10 个数据清洗任务——这正是 FlexGen 通过 CPU/磁盘 offload 换来的"单卡跑大模型"能力。

四、场景三:HELM 大规模评测基准

4.1 入口命令与参数

flexgen/apps/README.md 展示了用 FlexGen 运行 HELM 的 MMLU(Massive Multitask Language Understanding)场景示例:

python3 helm_run.py --description mmlu:model=text,subject=abstract_algebra,data_augmentation=canonical \ --pad-to-seq-len 512 --model facebook/opt-30b \ --percent 20 80 0 100 0 100 \ --gpu-batch-size 48 --num-gpu-batches 3 --max-eval-instance 100

该命令的关键配置:--pad-to-seq-len 512统一 padding 长度;--percent 20 80 0 100 0 100将 20% 权重放 GPU、80% 放 CPU、缓存与激活全部放 CPU(对应 helm_passed_30b.sh 中 OPT-IML-30B 的评测设置);--gpu-batch-size 48 --num-gpu-batches 3使有效批量为 144;--max-eval-instance 100限制评测实例数。

helm_run.py 在helm(HELM 0.2.1 版本)之上做了完整适配,其执行流水线(对应 helm_run.py 的run_entry函数)为:

  1. 通过RunEntry(description, ...)与run_entries_to_run_specs将场景描述解析为RunSpec;
  2. 用自定义OptTokenizer(包装 HuggingFace tokenizer,见 helm_run.py)创建 HELM adapter 与 scenario,拉取评测实例;
  3. get_batches将全部 prompt 按pad_to_seq_len统一 padding,并按gpu_batch_size * num_gpu_batches的有效批量切分成多个 batch(见 helm_run.py);若输入超长会按 256 的倍数自动向上取整重新 padding;
  4. execute初始化ExecutionEnv与Policy后逐 batch 调用model.generate(do_sample=True,温度从 HELM 请求映射而来,stop 序列映射为eos_token_id,见 helm_run.py);
  5. 将生成结果重组为 HELM 的RequestResult/ScenarioState,交由 HELM metric 评估(默认取第一个 metric),并把run_spec.json、scenario.json、scenario_state.json、stats.json、per_instance_stats.json等产物写入--run-path(默认runs)目录。

4.2 已通过的 HELM 场景清单

helm_fast_test.py 维护了一份经过验证的 HELM 场景清单(passed列表),涵盖:

  • 阅读理解/问答:boolq、narrative_qa、quac、natural_qa、commonsense、truthful_qa、msmarco、babi_qa;
  • 知识/推理:mmlu(如subject=abstract_algebra)、wikifact、math、gsm、synthetic_reasoning、synthetic_reasoning_natural、lsat_qa、med_qa;
  • 文本分类/毒性:imdb、raft、civil_comments、real_toxicity_prompts、bbq、bold;
  • 摘要:summarization_cnndm、summarization_xsum_sampled;
  • 语言学/语法:blimp、wikitext_103、twitter_aae、dyck_language;
  • 数据清洗:entity_matching(如dataset=Beer)、entity_data_imputation(如dataset=Buy);
  • 其他:legal_support、lextreme、lex_glue、copyright、disinformation、synthetic_efficiency。

helm_passed_30b.sh 则给出了在 OPT-IML-30B 上的完整实测命令,例如 WikiFact 与 MMLU:

model=facebook/opt-iml-30b # WikiFact (plaintiff),约 10 分钟 time python3 helm_run.py --description wikifact:model=text,k=5,subject=plaintiff \ --model $model --percent 20 80 0 100 0 100 --gpu-batch-size 96 --num-gpu-batches 3 --cpu \ --max-eval-instance 96 # MMLU (abstract_algebra),约 31 分钟 time python3 helm_run.py --description mmlu:model=together/opt-175b,subject=abstract_algebra,data_augmentation=canonical \ --model $model --percent 20 80 0 100 0 100 --gpu-batch-size 48 --num-gpu-batches 3 --cpu \ --max-eval-instance 100

注意:脚本中还包含--cpu标志与model=together/opt-175b这类来自 HELM 描述约定的占位字段,直接照搬仓库脚本即可复现;若自行构造--description,建议以 helm_fast_test.py 的passed清单为模板,并用--max-eval-instance控制评测规模。从 helm_fast_test.py 可看到其快速验证做法:先用facebook/opt-125m+ 全 GPU 策略 +--max-eval-instance 10验证场景跑通,再切换到目标大模型做完整评测。

五、offload 策略选型建议(基于仓库实测配置)

综合三个场景的脚本,可以归纳出仓库实测验证过的--percent配置规律:

模型规模典型配置适用硬件假设出处
OPT-6.7B100 0 100 0 100 016GB 显存即可全 GPUtest_batch_query_all_opt6.7b.sh
OPT-30B10 90 0 100 0 100/20 80 0 100 0 100单 T4 + 大内存test_batch_query_all_opt30b.sh、helm_passed_30b.sh
OPT-66B50 10 100 0 100 0+--compress-weight24GB 显存 + 32GB 内存flexgen/apps/README.md
OPT-175B0 50 0 0 0 100+--pin-weight 0单 T4 + 200GB DRAM + NVMe SSDtest_batch_query_all_opt175b.sh

选型要点(均有源码依据):

  • 六元组之和不必等于 100——权重的剩余比例会落到 NVMe 磁盘(w_disk_percent,见 flex_opt.py),这是 FlexGen 单卡跑百亿级模型的关键机制;
  • 数据清洗/评测类任务输入很长、输出很短,prefill 占绝对主导,此时把激活与缓存放在算力更强的设备(GPU 或高带宽内存)通常收益更大;
  • 量化压缩(--compress-weight/--compress-cache)可在不显著牺牲精度的前提下进一步压低显存峰值,与 offload 策略叠加使用;
  • 批量吞吐通过--gpu-batch-size × --num-gpu-batches控制,OPT-175B 脚本中单任务批量最高达 90(如 Restaurant 的86 × 1、Hospital 的50 × 4)。

六、总结

flexgen/apps/为 FlexGen 提供了三个可直接落地的应用入口:completion.py适合快速验证补全效果与 offload 配置;data_wrangle_run.py(含配套install.sh与 6 个测试脚本)覆盖实体匹配、数据补全、错误检测三类数据清洗任务,并在单张 T4 上实测了 6.7B/30B/175B 的吞吐数据;helm_run.py将 FlexGen 接入 HELM 评测体系,可稳定运行 MMLU、WikiFact、XSUM 等数十个场景。三者共享同一套Policy+--percent六元组 offload 编程模型,掌握了本文的参数表与配置规律,即可在受限单卡环境下按需组合出适合自己硬件预算的"单卡大模型"推理方案。更深入的调度与 offload 实现细节,可继续阅读 flexgen/flex_opt.py 与仓库根目录 README.md。

  • 推理引擎
  • 大模型

【免费下载链接】FlexGen

Running large language models on a single GPU for throughput-oriented scenarios.

项目地址:https://gitcode.com/gh_mirrors/fl/FlexGen
点击查看免费下载

相关推荐

上一篇:Rsbuild项目中的Bundle体积优化指南
下一篇:终极AVKit视频播放框架实战指南:从iOS8到现代iOS开发的演进之路 🎬

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询