binary-husky/gpt_academic · error · RuntimeError

Nougat解析论文失败。

Error message

Nougat解析论文失败。

What it means

Raised as RuntimeError by the Nougat paper-parsing helper when the external 'nougat' CLI ran but produced zero .mmd files under the output directory (glob(dst/'*.mmd') is empty). It means the nougat process exited without generating output — the command itself is not checked, only its result files. The lock is released before raising, so the failure is clean but uninformative.

Source

Thrown at crazy_functions/crazy_utils.py:630

    def NOUGAT_parse_pdf(self, fp, chatbot, history):
        from toolbox import update_ui_latest_msg

        yield from update_ui_latest_msg("正在解析论文, 请稍候。进度:正在排队, 等待线程锁...",
                                         chatbot=chatbot, history=history, delay=0)
        self.threadLock.acquire()
        import glob, threading, os
        from toolbox import get_log_folder, gen_time_str
        dst = os.path.join(get_log_folder(plugin_name='nougat'), gen_time_str())
        os.makedirs(dst)

        yield from update_ui_latest_msg("正在解析论文, 请稍候。进度:正在加载NOUGAT... (提示:首次运行需要花费较长时间下载NOUGAT参数)",
                                         chatbot=chatbot, history=history, delay=0)
        command = ['nougat', '--out', os.path.abspath(dst), os.path.abspath(fp)]
        self.nougat_with_timeout(command, cwd=os.getcwd(), timeout=3600)
        res = glob.glob(os.path.join(dst,'*.mmd'))
        if len(res) == 0:
            self.threadLock.release()
            raise RuntimeError("Nougat解析论文失败。")
        self.threadLock.release()
        return res[0]




def try_install_deps(deps, reload_m=[]):
    import subprocess, sys, importlib
    for dep in deps:
        subprocess.check_call([sys.executable, '-m', 'pip', 'install', '--user', dep])
    import site
    importlib.reload(site)
    for m in reload_m:
        importlib.reload(__import__(m))


def get_plugin_arg(plugin_kwargs, key, default):
    # 如果参数是空的

View on GitHub (pinned to d6bde0fa54)

Solutions

  1. Run the exact command manually to see nougat's stderr: nougat --out /tmp/nout path/to/paper.pdf
  2. Verify nougat is correctly installed and on PATH: which nougat && nougat --version (pip install nougat-ocr, NOT pip install nougat which is a different package)
  3. Check the dst log folder for partial output/nougat error traces left by the run
  4. If the PDF is scanned/image-only, OCR it first or use a different parser — nougat needs a text layer
  5. For very large PDFs, raise the timeout or split the document

Example fix

// before
self.nougat_with_timeout(command, cwd=os.getcwd(), timeout=3600)
res = glob.glob(os.path.join(dst, '*.mmd'))
if len(res) == 0:
    self.threadLock.release()
    raise RuntimeError("Nougat解析论文失败。")

// after
ret = self.nougat_with_timeout(command, cwd=os.getcwd(), timeout=3600)
res = glob.glob(os.path.join(dst, '*.mmd'))
if len(res) == 0:
    self.threadLock.release()
    raise RuntimeError(f"Nougat解析论文失败 (exit={getattr(ret, 'returncode', '?')}, out={dst})")
Defensive patterns

Strategy: validation

Validate before calling

import shutil, subprocess

def nougat_ready(pdf_path: str) -> tuple[bool, str]:
    if shutil.which('nougat') is None:
        return False, 'nougat not on PATH'
    if not Path(pdf_path).suffix.lower() == '.pdf':
        return False, 'input must be a .pdf'
    return True, 'ok'

Type guard

def has_text_layer(pdf_path: str) -> bool:
    """Nougat needs extractable text; scanned-only PDFs usually fail."""
    try:
        from pypdf import PdfReader
        return any(p.extract_text().strip() for p in PdfReader(pdf_path).pages[:3])
    except Exception:
        return False

Try / catch

try:
    mmd = nougat_parse(fp)
except RuntimeError as e:
    if 'Nougat' in str(e):
        log.error('nougat produced no .mmd; run `nougat --out /tmp/nout %s` manually', fp)
        mmd = fallback_pdf_to_markdown(fp)  # e.g. markitdown route
    else:
        raise

Prevention

When it happens

Trigger: nougat_with_timeout(['nougat', '--out', dst, fp]) completes but nougat crashes on the PDF (corrupt/scanned pages), nougat is a stub/wrong binary, the PDF path contains characters nougat mishandles, or the 3600s timeout silently killed the run mid-processing.

Common situations: First-run environments where nougat's model download failed or its deps (torch/pypdf) are broken; scanned/image-only PDFs with no text layer; nougat not on PATH resolves to something else (exit 0, no output); very large PDFs hitting the 1-hour timeout.

Related errors


AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14). Data as JSON: /api/errors/0a423e435cc8cd7e. Report an issue: GitHub.