能否使用两块12GB显存的Titan X GPU运行olmocr?
当然可以试试通过多GPU适配来解决这个问题!直接像合并内存那样把两块卡的显存“拼接”成24GB统一使用在消费级GPU上做不到,但我们可以通过模型并行的方式把模型拆分到两块卡上,避开单卡显存不足的限制,具体可以按下面的步骤来操作:
先修改显存检查逻辑
报错里的olmocr.check模块是在检查单卡显存是否达标,你可以找到项目里的check.py文件(一般在olmocr目录下),找到类似判断单卡显存的代码,比如:for i in range(torch.cuda.device_count()): props = torch.cuda.get_device_properties(i) if props.total_memory >= 20 * 1024**3: return True raise RuntimeError("Torch was not able to find a GPU with at least 20 GB of RAM.")你可以把这个逻辑改成检查所有卡的总显存,或者先暂时注释掉这个检查(不过注释后如果模型加载时显存不够会直接报错,所以最好配合后面的模型并行修改)。
用模型并行拆分模型
因为你的单卡装不下整个20GB的模型,所以可以把模型的不同组件分配到两块GPU上。比如把模型的编码器部分放在第一块卡(cuda:0),解码器放在第二块卡(cuda:1),举个简单的修改示例:# 原模型加载代码大概是这样 model = OLMOCRModel.from_pretrained("path/to/model") model = model.cuda() # 修改为模型并行分配 model.encoder = model.encoder.to("cuda:0") model.decoder = model.decoder.to("cuda:1") # 同时要调整前向传播的设备适配 def custom_forward(x): # 把输入数据传到编码器所在的卡 x = x.to("cuda:0") encoded_features = model.encoder(x) # 把编码后的特征传到解码器所在的卡 encoded_features = encoded_features.to("cuda:1") output = model.decoder(encoded_features) return output # 替换模型的前向传播方法(或者在调用时按这个逻辑处理) model.forward = custom_forward这样修改后,模型的不同部分分别占用两块卡的显存,总显存就够了。
注意细节调整
调整过程中要留意设备不匹配的问题:比如损失函数的计算要和输出在同一设备,数据加载时的设备分配,还有一些中间张量的传递都要手动指定设备。另外,如果olmocr本身有提供多GPU相关的配置选项,你可以先看看项目的README或者配置文件,说不定只需要开启某个参数就能启用多GPU支持,不用手动改这么多代码。
如果模型并行的修改对你来说有点复杂,也可以试试分布式数据并行(DDP),不过DDP是把模型复制到每块卡上,单卡还是需要装下整个模型,所以这个方法可能不适合你的情况,优先考虑模型并行更靠谱。
备注:内容来源于stack exchange,提问作者Dandelion

