发现hanlp解析时有可能陷入死循环,出现递归错误

提示错误RecursionError: maximum recursion depth exceeded while calling a Python object,是在我写了个脚本自动分析语料的时候发生的,因此不知道具体是哪一句话出现了错误。何老师或其他同学不知道可以看看吗~

以下是完整报错信息。72~76行是我的脚本,其余都是hanlp包内的代码,不知道是hanlp的代码出了问题吗?

in count_syntax_information(input_path)

     72                   res = re.search('[^\u4E00-\u9FA5“︰<?。(;‘’)?">﹒〈”:。》(,、)…——.~〉·!《!・]', i) #寻找有没有汉字及汉语标点以外的字符
     73                   if len(i) != 0 and len(i) > 4 and res == None:
---> 74                     hanlp_result=HanLP(i)
     75                   else:
     76                     continue

/usr/local/lib/python3.8/dist-packages/hanlp/components/pipeline.py in call(self, doc, **kwargs)

    144             doc = Document(**kwargs)
    145         for component in self:
--> 146             doc = component(doc)
    147         return doc
    148

/usr/local/lib/python3.8/dist-packages/hanlp/common/component.py in call(self, *args, **kwargs)

     34 
     35         """
---> 36         return self.predict(*args, **kwargs)

/usr/local/lib/python3.8/dist-packages/hanlp/components/pipeline.py in predict(self, doc, **kwargs)

     50         if unpack:
     51             kwargs['_hanlp_unpack'] = True
---> 52         output = self.component(input, **kwargs)
     53         if isinstance(output, types.GeneratorType):
     54             output = list(output)

/usr/local/lib/python3.8/dist-packages/torch/autograd/grad_mode.py in decorate_context(*args, **kwargs)

     25         def decorate_context(*args, **kwargs):
     26             with self.clone():
---> 27                 return func(*args, **kwargs)
     28         return cast(F, decorate_context)
     29

/usr/local/lib/python3.8/dist-packages/hanlp/common/torch_component.py in call(self, *args, **kwargs)

    636             **kwargs: Used in sub-classes.
    637         """
--> 638         return super().__call__(*args, **merge_dict(self.config, overwrite=True, **kwargs))

/usr/local/lib/python3.8/dist-packages/hanlp/common/component.py in call(self, *args, **kwargs)

     34 
     35         """
---> 36         return self.predict(*args, **kwargs)

/usr/local/lib/python3.8/dist-packages/hanlp/components/parsers/biaffine/biaffine_dep.py in predict(self, data, batch_size, batch_max_tokens, conll, **kwargs)

     61         for batch in dataloader:
     62             arc_scores, rel_scores, mask, puncts = self.feed_batch(batch)
---> 63             self.collect_outputs(arc_scores, rel_scores, mask, batch, predictions, order, data, use_pos,
     64                                  build_data)
     65         outputs = self.post_outputs(predictions, data, order, use_pos, build_data, conll=conll)

/usr/local/lib/python3.8/dist-packages/hanlp/components/parsers/biaffine/biaffine_dep.py in collect_outputs(self, arc_scores, rel_scores, mask, batch, predictions, order, data, use_pos, build_data)

    127                         build_data):
    128         lens = [len(token) - 1 for token in batch['token']]
--> 129         arc_preds, rel_preds = self.decode(arc_scores, rel_scores, mask, batch)
    130         self.collect_outputs_extend(predictions, arc_preds, rel_preds, lens, mask)
    131         order.extend(batch[IDX])

/usr/local/lib/python3.8/dist-packages/hanlp/components/parsers/biaffine/biaffine_dep.py in decode(self, arc_scores, rel_scores, mask, batch)

    544         tree, proj = self.config.tree, self.config.get('proj', False)
    545         if tree:
--> 546             arc_preds = decode_dep(arc_scores, mask, tree, proj)
    547         else:
    548             arc_preds = arc_scores.argmax(-1)

/usr/local/lib/python3.8/dist-packages/hanlp/components/parsers/alg.py in decode_dep(s_arc, mask, tree, proj)

    757             alg = mst
    758             s_arc.diagonal(0, 1, 2)[1:].fill_(float('-inf'))
--> 759         arc_preds[bad] = alg(s_arc[bad], mask[bad])
    760 
    761     return arc_preds

/usr/local/lib/python3.8/dist-packages/hanlp/components/parsers/alg.py in eisner(scores, mask)

    187     for i, length in enumerate(lens.tolist()):
    188         heads = p_c.new_zeros(length + 1, dtype=torch.long)
--> 189         backtrack(p_i[i], p_c[i], heads, 0, length, True)
    190         preds.append(heads.to(mask.device))
    191

/usr/local/lib/python3.8/dist-packages/hanlp/components/parsers/alg.py in backtrack(p_i, p_c, heads, i, j, complete)

    174         if complete:
    175             r = p_c[i, j]
--> 176             backtrack(p_i, p_c, heads, i, r, False)
    177             backtrack(p_i, p_c, heads, r, j, True)
    178         else:

/usr/local/lib/python3.8/dist-packages/hanlp/components/parsers/alg.py in backtrack(p_i, p_c, heads, i, j, complete)

    180             i, j = sorted((i, j))
    181             backtrack(p_i, p_c, heads, i, r, True)
--> 182             backtrack(p_i, p_c, heads, j, r + 1, True)
    183 
    184     preds = []

… last 2 frames repeated, from the frame below …

/usr/local/lib/python3.8/dist-packages/hanlp/components/parsers/alg.py in backtrack(p_i, p_c, heads, i, j, complete)

    174         if complete:
    175             r = p_c[i, j]
--> 176             backtrack(p_i, p_c, heads, i, r, False)
    177             backtrack(p_i, p_c, heads, r, j, True)
    178         else:

RecursionError: maximum recursion depth exceeded while calling a Python object

请提供复现代码以及版本号,特别是触发bug的具体句子,让人一运行就可以看到报错。

抱歉何老师,最近有些忙。我后来用一个try except语句就能捕捉到出问题的句子并且跳过它们对它们不作处理。严格来说这些应该不算句子,而是维基语料里没有清洗干净导致出现的一长串名词的罗列。在调用依存句法分析工具(如hanlp.load(hanlp.pretrained.dep.PMT1_DEP_ELECTRA_SMALL))进行分析时就会报这种错。

hanlp版本号为2.1.0b45
目前一共捕捉到如下两个“句子”会导致这个问题:
[‘麻黄桂枝紫苏生姜香薷荆芥防风羌活白芷细辛辛夷苍耳子藁本葱白灯盏细辛鹅不食草薄荷柴胡葛根牛蒡子蝉蜕桑叶菊花升麻淡豆豉蔓荆子浮萍木贼桉叶蕤仁山芝麻石膏知母栀子芦根天花粉淡竹叶夏枯草决明子鸭跖草青葙子密蒙花谷精草熊胆黄芩黄连黄柏龙胆草苦参秦皮白鲜皮金银花大青叶板蓝根青黛贯众蒲公英连翘野菊花紫花地丁鱼腥草败酱红藤土茯苓白花蛇舌草白头翁马齿苋鸭胆子射干山豆根马勃穿心莲一枝黄花重楼拳参半边莲半枝莲垂盆草金荞麦四季青万年青白蔹漏芦千里光白药子葎草冬凌草龙葵蛇莓天葵子山慈菇生地黄玄参牡丹皮赤芍紫草水牛角青蒿地骨皮银柴胡胡黄连荷叶绿豆白薇大黄芒硝番泻叶芦荟火麻仁郁李仁甘遂京大蓟芫花巴豆牵牛子商路千金子狼毒蓖麻子独活威灵仙川乌木瓜蕲蛇乌梢蛇秦艽防巳臭梧桐络石藤豨莶草桑枝雷公藤盾翅藤蚕沙丝瓜络五加皮桑寄生狗脊千年健藿香佩兰苍术厚朴砂仁豆蔻草果茯苓薏苡仁猪苓泽泻赤小豆冬瓜皮玉米须泽漆蟋蟀车前子石韦木通通草滑石扁蓄瞿麦地肤子海金沙萆薢冬葵子茵陈蒿金钱草虎杖田基黄白英附子干姜肉桂吴茱萸小茴香高良姜丁香胡椒花椒荜苃荜澄茄陈皮青皮佛手枳实木香沉香檀香川楝子香附乌药荔枝核薤白柿蒂娑罗子八月札绿梅花九香虫山楂神曲麦芽谷芽莱菔子鸡内金使君子苦楝皮槟榔南瓜子鹤草芽雷丸鹤虱痱子芜荑大蓟小蓟地榆侧柏叶槐花白茅根苎麻根羊蹄断血流三七茜草蒲黄藕节卷柏白及仙鹤草棕榈炭血余炭艾叶炮姜灶心土川芎郁金姜黄延胡索乳香没药五灵脂丹参红花桃仁益母草牛膝鸡血藤王不留行月季花马钱子骨碎补苏木自然铜莪术三棱水蛭虻虫穿山甲地鳖虫蜣螂半夏天南星禹白附白芥子钟乳石瓜蒌川贝母浙贝母竹茹竹沥天竺黄桔梗前胡海藻昆布紫苏子乌蛇胆胖大海藏青果挂金灯罗汉果木蝴蝶礞石蛤壳苦杏仁苏子百部紫菀款冬花马兜铃枇杷叶桑白皮葶苈子白果白前朱砂磁石龙骨琥珀珍珠紫石英酸枣仁柏子仁远志合欢皮夜交藤石决明珍珠母牡蛎代赭石刺蒺藜罗布麻叶羚羊角钩藤牛黄天麻地龙全蝎蜈蚣白僵蚕蛇蜕麝香冰片苏合香安息香石菖蒲人参西洋参党参太子参黄芪白术山药甘草大枣蜂蜜白扁豆刺五加当归熟地黄白芍阿胶何首乌龙眼肉鸡血藤绿矾鹿茸鹿角紫河车淫羊藿巴戟天仙茅杜仲续断肉苁蓉锁阳补骨脂益智仁菟丝子沙苑子白蒺藜潼蒺藜蛤蚧核桃仁冬虫夏草北沙参南沙参百合麦冬天冬玉竹黄精枸杞子墨旱莲女贞子鳖甲龟板石斛麻黄根浮小麦碧桃干五味子五倍子乌梅诃子肉豆蔻罂粟壳赤石脂禹余粮石榴皮椿皮山茱萸覆盆子桑螵蛸金樱子海螵蛸莲子芡实益智仁南烛子常山瓜蒂胆矾藜芦雄黄硫磺白矾蛇床子蟾酥樟脑木鳖子土荆皮蜂房大蒜斑蝥大风子仁木槿皮木芙蓉叶藤黄儿茶升药轻粉红粉砒石铅丹炉甘石硼砂’]
[‘彭德怀、杨根思、黄继光、伍先华、许家朋、孙占元、邱少云、李家发、杨连第、杨春增、杨育才、胡修道杨根思、黄继光于喜田、于泮功、王兆才、王海、王德明、王学风、毛国臣、孔庆三、任宝山、伍先华、李延年、李凤林、李家发、邱少云、沈树根、吴志洲、余新发、周厚刚、赵宝桐、胡修道、柴云振、高成山、高景灏、秦建彬、徐长富、陈德中、倪祥明、郭忠田、郭恩志、孙占元、孙生禄、黄家富、曹庆功、曹玉海、崔建国、张永富、张积慧、杨保山、杨连第、杨春增、雷保森、鲁珉、刘庆亮、刘维汉、刘玉堤、阎成恩、谭炳云王兴记、孙凤钜、张益仁、罗盛教卜广德、毛张苗、孙振禄、魏玉德王天保、王保江、王合良、王彦林、田立明、平太信、冉隆华、牧保才、朱金池、朱溶堂、吕暮祥、安炳勋、李文彦、李祥、李忠先、李元兴、李经盛、余贵、宋兰君、易才学、林炳远、周德高、房志忠、房光超、胡连、范万章、郝兴文、郝志新、高云和、高良伦、马新年、陈治国、陈吉、徐连才、徐恒禄、梁振龙、许天良、孙子明、康治平、曹光景、黄丑和、焦景文、董明德、张像山、张建明、张兰亭、程云庆、粟振林、杨振玉、杨国良、葛洪臣、葛英东、万子扬、农廷秋、郑起、郑金钵、蔡兴海、赖永泽、赖发均、邓章德、蒋道平、蒋永德、刘钦、刘继和、刘凤勇、刘俊卿、欧文辉、龙世昌、薛志高、戴荣华、庞殿臣、关崇贵吕玉久、胡金华、陈振安、张明禄于水林、王锁昌、王云阁、王克得、王万夏、王兴义、王元义、王庆琳、王志、牛锡浩、孔范玉、任西和、李国玉、李秀德、李树森、李家芝、李太林、李吉武、李玉才、李汉、杜树君、邢连富、车臣才、冷树国、周信仁、周平、周腊生、林贵远、吴少贵、吴胜凯、邵凤阳、金克智、姚显儒、徐邦礼、徐文斌、徐申、徐生、马天明、马一钧、马如华、袁孝文、梁封、孙明芝、孙克荣、高润田、高守余、高胜德、高月明、梅怀青、许长友、崔长海、崔贵江、陆廷高、陈少青、陈忠贤、陈启瑶、黄万丰、曹殿生、乔永生、曾平章、曾南生、曾少才、毕武斌、郭隆楷、张希瑞、张振华、张豪、张宝富、张渭良、张来元、张文兰、张良广、张万荣、傅庆祥、傅绍斌、杨伯钊、杨锡生、杨树华、褚庆然、叶君、邹炎、赵恒志、赵柏生、董恒志、裴景善、刘保成、刘四、刘久恒、刘福海、刘光子、阎洪全、樊金明、蔡金同、蔡朝兴、郑定富、郑长华、萧桂强、蒋元伦、骆家奎、韩勤忠、韩德彩、简海金、谭朝志、苏文俊、欧阳代炎武在元于凤泉、于溪源、于宪桂、王紫龙、王明学、王顺义、王永维、任廷昌、朱重元、李文臣、李华云、杜福先、杜占山、岳吉齐、林波、施玉南、姚小遂、席忠、陈汉文、陈达志、陆善清、许景春、程山堂、靳国华、黄明德、张培芝、张灿、张振智、曾荣廷、喻忠奎、赵尔云、赵宪法、赵金贵、杨殿超、杨在先、熊克恒、刘树德、刘保英、刘秀珍、钱良生、薛文德、薛其德、罗德顺、苏志明、耀先于德江、王万成、王安全、王兴邦、王荣、王凤江、文汉春、牛喜生、牛瑞山、方国发、尹继发、史朝珍、史仁和、甘士亮、朱有光、宋新文、何家胜、邱宪章、吕学敏、李炳舟、李洪序、李春长、李光禄、李德贵、李满、李玉、李占广、李飞、李德学、李海清、牟士清、金耳世、吴儒林、胡志先、胡照春、侯柏锁、陈述中、陈德清、陈其昌、陈宝喜、陈开茂、陈任华、陈亮、陈佑甫、郭正喜、郭金升、徐忠、梁庆友、孙敬珍、孙忠国、唐章洪、许洪斌、黄德明、隋春暖、华龙毅、张怀英、张光生、张炳恒、张瑞臣、张桃芳、张续计、张守义、张书明、张昭义、张才树、崔含弼、彭福礼、逯松亭、杨育才、杨保明、赵毛臣、赵玉忠、赵连山、赵先有、郑恩喜、齐子英、潘正光、萧子云、刘万寿、刘金生、刘桃顺、刘东武、卢耀文、鲁清芳、罗子周、罗沧海、谭芳云、苏世英、顾洪臣’]

无法复现。可能是你系统的recursionlimit太小,解决方案:

1 Like

原来可以设置这个的啊,谢谢何老师解惑