我记得昨天咱们也是吃上虚拟细胞敲除这碗饭了是吧,从R语言到python,咱们也是一顿搞起来了,今天我来发一个debug的内容,都是基于我跑的python后给我的反馈。
1.python函数包里面的内容不一致
报错信息如下:
Matplotlib is building the font cache; this may take a moment.---------------------------------------------------------------------------ImportError Traceback (most recent call last)Cell In[1], line 4 2 import numpy as np 3 import scanpy as sc----> 4 from gears import PerturbData, GEARSImportError: cannot import name 'PerturbData' from 'gears' (/data/hs007/.conda/envs/gears_env/lib/python3.9/site-packages/gears/__init__.py)
我当时是直接tab补齐了参数,所以我也没细看这个内容。所以提示报错了,原来错误的代码是这样的:
import pandas as pdimport numpy as npimport scanpy as scfrom gears import PerturbData, GEARSprint("正在唤醒虚拟细胞大模型 (GEARS)...")# 1. 载入底层训练环境与知识图谱# 我们使用 Norman 等人构建的经典泛癌细胞系扰动数据集作为基石pert_data = PerturbData('./data')pert_data.load(data_name = 'norman') pert_data.prepare_split(split = 'simulation', seed = 1)pert_data.get_dataloader(batch_size = 32, test_batch_size = 128)
在这里我们只需要把一个参数把 PerturbData 替换为正确的 PertData。这回就可以跑通了,修改后的代码如下:
import pandas as pdimport numpy as npimport scanpy as scfrom gears import PertData, GEARSprint("正在唤醒虚拟细胞大模型 (GEARS)...")# 1. 载入底层训练环境与知识图谱# 我们使用 Norman 等人构建的经典泛癌细胞系扰动数据集作为基石pert_data = PertData('./data')pert_data.load(data_name = 'norman') pert_data.prepare_split(split = 'simulation', seed = 1)pert_data.get_dataloader(batch_size = 32, test_batch_size = 128)
2.因为网络被限制,所以很难读取到文件
# 1. 载入底层训练环境与知识图谱# 我们使用 Norman 等人构建的经典泛癌细胞系扰动数据集作为基石pert_data = PertData('./data')pert_data.load(data_name = 'norman') pert_data.prepare_split(split = 'simulation', seed = 1)pert_data.get_dataloader(batch_size = 32, test_batch_size = 128)Downloading...100%|██████████| 118/118 [00:00<00:00, 208kiB/s]---------------------------------------------------------------------------UnpicklingError Traceback (most recent call last)Cell In[7], line 5 1 File ~/.conda/envs/gears_env/lib/python3.9/site-packages/gears/pertdata.py:96, in PertData.__init__(self, data_path, gene_set_path, default_pert_graph) 93 dataverse_download(server_path, 94 os.path.join(self.data_path, 'gene2go_all.pkl')) 95 with open(os.path.join(self.data_path, 'gene2go_all.pkl'), 'rb') as f:---> 96 self.gene2go = pickle.load(f)UnpicklingError: invalid load key, '<'.
这意味着你服务器网络在连接哈佛大学的 Dataverse 数据库时被拦截了,代码并没有下载到真正的几十兆的数据包。原本计划在terminus里下载的,但是遇到了经典的403forbidden。哈佛大学的数据库(Dataverse)开启了反爬虫防火墙。它识别出是在用 wget 这个纯代码工具去“白嫖”数据,而不是一个真正的人类在使用浏览器,所以直接把你的请求给拦截了。于是我不得不换一个方式下载。
在你自己电脑的浏览器里下载
请直接把你电脑的浏览器(就是你平时上网的 Chrome 或 Edge)打开,新建一个标签页,把下面这个网址复制进去并回车: https://dataverse.harvard.edu/api/access/datafile/6153417这时你的浏览器会弹出一个真正的下载任务。下载下来的文件可能叫 gene2go.pkl,请一定要在你的电脑上把它重命名为 gene2go_all.pkl。并且上传到目前python端页面的文件夹,也就是data这个文件夹里面。
但是依旧是报错
Downloading...100%|██████████| 118/118 [00:00<00:00, 429kiB/s]---------------------------------------------------------------------------UnpicklingError Traceback (most recent call last)Cell In[15], line 5 1 # ============================================================================== 2 # 1. 载入底层训练环境与知识图谱 3 # ============================================================================== 4 # 我们使用 Norman 等人构建的经典泛癌细胞系扰动数据集作为基石----> 5 pert_data = PertData('./data') 6 pert_data.load(data_name = 'norman') 7 pert_data.prepare_split(split = 'simulation', seed = 1)File ~/.conda/envs/gears_env/lib/python3.9/site-packages/gears/pertdata.py:96, in PertData.__init__(self, data_path, gene_set_path, default_pert_graph) 93 dataverse_download(server_path, 94 os.path.join(self.data_path, 'gene2go_all.pkl')) 95 with open(os.path.join(self.data_path, 'gene2go_all.pkl'), 'rb') as f:---> 96 self.gene2go = pickle.load(f)UnpicklingError: invalid load key, '<'.还是报错啊,咋回事
这个错误说明这个 gears包的代码太死板了! 它的底层源码里写死了强制下载逻辑(哪怕本地有文件,它也可能因为某些验证机制强行重新下)。所以,当你运行 PertData('./data') 时,大模型连招呼都不打,直接去连哈佛大学的服务器,再次被拦截(拿到 118 字节的报错网页),然后它极其粗暴地把你辛辛苦苦传上去的 6.4MB 真文件给覆盖(替换)了! 接着它去读取这个被搞坏的文件,理所当然又读到了 < 并崩溃。
为了应对这个错误,只能运行下面这个代码来保证你的数据不被限制掉
import osimport gears.pertdata# 1. 强行改名:治好大模型的“强迫症”old_name = './data/gene2go.pkl'new_name = './data/gene2go_all.pkl'if os.path.exists(old_name): os.rename(old_name, new_name)print("✨ 强迫症治愈:已将文件重命名为 gene2go_all.pkl!")# 2. 核心黑客科技:防覆盖补丁gears.pertdata.dataverse_download = lambda url, path: print("🛑 拦截成功:已阻止底层流氓下载覆盖机制!")from gears import PertData, GEARS# 3. 正式点火,启动大模型底座if os.path.exists(new_name) and os.path.getsize(new_name) > 1024 * 1024:print("🚀 万事俱备,哈佛知识图谱已就位,开始点火!")# 这一步绝对不会再报错了! pert_data = PertData('./data')print("✅ 知识图谱载入完毕!")print("⏳ 准备拉取真正的细胞系敲除测序数据 (Norman 数据集),请耐心等待进度条...") pert_data.load(data_name = 'norman') pert_data.prepare_split(split = 'simulation', seed = 1) pert_data.get_dataloader(batch_size = 32, test_batch_size = 128)print("🎉🎉 第一阶段全线通关!模型底座已就绪!赶紧把后面的预测代码接上!")else:print("🚨 完了,这属于灵异事件了,文件又凭空消失了...")
3.果不其然运行完发现还是报错
核心的错误点:BadZipFile: File is not a zip file你会发现他不是你期待的zip格式,而且数据看起来也不对。经过我查看网站,发现真正的文件是这个:https://dataverse.harvard.edu/api/access/datafile/6154020复制这个链接才能下载到真正的数据。然后再运行下面的这段代码:
import osimport zipfileimport gears.utils# 1. 终极防覆盖补丁:直接掐断底层工具包的下载函数gears.utils.dataverse_download = lambda url, path: print("🛑 拦截:已阻止覆盖 norman.zip!")from gears import PertData, GEARSzip_path = './data/norman.zip'# 2. 检查你上传的真包if os.path.exists(zip_path): size_mb = os.path.getsize(zip_path) / (1024 * 1024)if size_mb < 1.0:print(f"🚨 警报!当前的 norman.zip 只有 {size_mb:.2f} MB,这还是那个假文件!请删除后重新上传真包!")else:print(f"✅ 确认真实的 norman.zip 已就位 ({size_mb:.2f} MB)!准备强行手动解压...")# 3. 绕过大模型的傻瓜代码,我们自己用 Python 解压 try: with zipfile.ZipFile(zip_path, 'r') as zip_ref: zip_ref.extractall('./data')print("🎉 解压完成!真实测序数据已释放!") # 4. 再次点火:这一次大模型看到解压好的文件夹,会直接跳过所有下载!print("🚀 启动大模型底座...") pert_data = PertData('./data') pert_data.load(data_name = 'norman') pert_data.prepare_split(split = 'simulation', seed = 1) pert_data.get_dataloader(batch_size = 32, test_batch_size = 128)print("🏆 恭喜!九九八十一难全部渡劫成功!大模型数据已 100% 准备就绪!")print("下一步:你可以把敲除 FAM111B 的预测代码直接贴到下面运行了!") except zipfile.BadZipFile:print("❌ 解压失败!虽然文件很大,但可能下载时损坏了,请重新下载 norman.zip!")else:print("📁 还没有找到 norman.zip,请在 data 文件夹里确认是否上传成功。")
需要注意 把你下载下来的包重命名为 norman.zip,然后上传到服务器的 data 文件夹里。
4.还是缺文件
---------------------------------------------------------------------------FileNotFoundError Traceback (most recent call last)Cell In[23], line 29 27 print("🚀 启动大模型底座...") 28 pert_data = PertData('./data')---> 29 pert_data.load(data_name = 'norman') 30 pert_data.prepare_split(split = 'simulation', seed = 1) 31 pert_data.get_dataloader(batch_size = 32, test_batch_size = 128)File ~/.conda/envs/gears_env/lib/python3.9/site-packages/gears/pertdata.py:183, in PertData.load(self, data_name, data_path) 178 else: 179 raise ValueError("data attribute is either norman, adamson, dixit " 180 "replogle_k562 or replogle_rpe1 " 181 "or a path to an h5ad file")--> 183 self.set_pert_genes() 184 print_sys('These perturbations are not in the GO graph and their ' 185 'perturbation can thus not be predicted') 186 not_in_go_pert = np.array(self.adata.obs[ 187 self.adata.obs.condition.apply( 188 lambda x:not filter_pert_in_go(x, 189 self.pert_names))].condition.unique())File ~/.conda/envs/gears_env/lib/python3.9/site-packages/gears/pertdata.py:123, in PertData.set_pert_genes(self) 120 path_ = os.path.join(self.data_path, 121 'essential_all_data_pert_genes.pkl') 122 dataverse_download(server_path, path_)--> 123 with open(path_, 'rb') as f: 124 essential_genes = pickle.load(f) 126 gene2go = {i: self.gene2go[i] for i in essential_genes if i in self.gene2go}FileNotFoundError: [Errno 2] No such file or directory: './data/essential_all_data_pert_genes.pkl'
本来以为上面我已经解决好了那些问题,结果运行起来发现还是缺个文件;道理是一样,在你自己的电脑上下载这个小文件 打开你电脑的浏览器,复制并访问下面这个底层直链:👉 https://dataverse.harvard.edu/api/access/datafile/6934320第二步:确认文件名 下载下来的文件应该很小(不到 1MB)。请务必确保它的名字完完全全叫这个(一个字母都不能错): essential_all_data_pert_genes.pkl 第三步:上传 把它上传到你服务器的 data 文件夹里。
目前为止,我们step1的错误debug都结束了,上传最新的代码如下:
import osimport zipfileimport gears.utils# 1. 终极防覆盖补丁:直接掐断底层工具包的下载函数gears.utils.dataverse_download = lambda url, path: print("🛑 拦截:已阻止覆盖 norman.zip!")from gears import PertData, GEARSzip_path = './data/norman.zip'# 2. 检查你上传的真包if os.path.exists(zip_path): size_mb = os.path.getsize(zip_path) / (1024 * 1024)if size_mb < 1.0:print(f"🚨 警报!当前的 norman.zip 只有 {size_mb:.2f} MB,这还是那个假文件!请删除后重新上传真包!")else:print(f"✅ 确认真实的 norman.zip 已就位 ({size_mb:.2f} MB)!准备强行手动解压...")# 3. 绕过大模型的傻瓜代码,我们自己用 Python 解压 try: with zipfile.ZipFile(zip_path, 'r') as zip_ref: zip_ref.extractall('./data')print("🎉 解压完成!真实测序数据已释放!")# 4. 再次点火:这一次大模型看到解压好的文件夹,会直接跳过所有下载!print("🚀 启动大模型底座...") pert_data = PertData('./data') pert_data.load(data_name = 'norman') pert_data.prepare_split(split = 'simulation', seed = 1) pert_data.get_dataloader(batch_size = 32, test_batch_size = 128)print("🏆 恭喜!九九八十一难全部渡劫成功!大模型数据已 100% 准备就绪!")print("下一步:你可以把敲除 FAM111B 的预测代码直接贴到下面运行了!") except zipfile.BadZipFile:print("❌ 解压失败!虽然文件很大,但可能下载时损坏了,请重新下载 norman.zip!")else:print("📁 还没有找到 norman.zip,请在 data 文件夹里确认是否上传成功。")
好了今天的debug就到这吧,累了,明天我们继续debug,代码虽然是可以无限写,但是当你真的去试一下就知道实际的问题是啥了。欢迎大家继续跟我交流并且发出来自己的debug。