はじめに
ChatGPTを利用して、自動で論文を翻訳したい人はたくさんいると思います。しかし、PDFの壁、403 Forbiddenの壁、Token数の壁などに阻まれて、サクッとはいきませんよね。
この記事では、オレオレツールを利用して、ChatGPTを利用して論文を日本語に翻訳する方法を紹介しています。あまり整頓された方法ではありませんが、誰がやっても原則は変わらないと思うので、同じようなことをしようとしている誰かの参考になると幸いです。
基本方針
利用するツール
- Firefox - ブラウザ
- Zotero - 文献管理ソフト
- Ruby - 動的プログラミング言語
- chatgpt-cli - Crystal製のオレオレコマンドラインツール
このページに書いたスクリプトの一部は以下のリポジトリに移管しました。
論文からテキストを抽出する
まずは論文からテキストを抽出します。PDFではなくHTMLからスクレイピングをします。(スクレイピングには「XPath」を使います)しかし、論文が掲載されている多くのウェブサイトは簡単にはスクレイピングをさせてくれません。403 Forbidden になってしまいます。 そこで、まず「Zotero」を使ってスナップショットをローカルに保存し、そのローカルのHTMLファイルに対してスクレイピングを行います。(この方法はCell系の雑誌で有効です)
① Zoteroに論文を保存する
文献管理ツールZoteroに論文を保存します。私はFirefox拡張を利用しています。保存された論文右クリックして「スナップショットを閲覧する」を選択すると、ローカルに保存されたHTMLをブラウザで開くことができます。
/home/kojix2/Zotero/storage/HOGEFUGA/S1234567890123456789.html
このファイルパスをあとで使用します。
② FirefoxでXPathを確認する
Token数の制限に対処するために、論文を各セクションごとに分割してファイルに保存します。まず、HTMLで各セクションがどのように表現されているのか調べます。
Firefoxの画面で、論文本文中の「調査」をクリックします。インスペクタを開き、HTMLのソースコードを確認します。例えばCell紙の場合は、以下のようにセクションが並んでいることがわかります。
右クリックで、「コピー」>「XPath」を選択します。すると、XPathがクリップボードにコピーされます。
//*[@id="sec1"]
このXPathに対応する本文を抽出し、適切に改行をするような小さなコマンドラインツールをRubyで書きました。どうせなら再利用したいので、コマンドラインオプションなどをいろいろつけた結果すこし長くなっています。(コードのほとんどはChatGPTに生成させました)
require 'nokogiri'
require 'optparse'
require 'fileutils'
options = {}
OP = OptionParser.new do |opts|
opts.banner = 'Usage: kirinuki.rb [options]'
opts.separator ''
opts.separator "Example: ruby kirinuki.rb -f 'path/to/your.html' -p '//*[@id=\"sec数\"]' -r '1..12'"
opts.on('-f', '--file HTML_PATH', 'HTML file path') { |v| options[:file] = v }
opts.on('-p', '--pattern PATTERN', 'Pattern') { |v| options[:pattern] = v }
opts.on('-r', '--range RANGE', 'Range') { |v| options[:range] = v }
opts.on('-o', '--output OUTPUT_DIR', 'Output directory') { |v| options[:output] = v }
end
def show_help_and_quit
warn(OP)
exit 1
end
begin
OP.parse!
rescue StandardError
show_help_and_quit
end
html_path = options[:file] || show_help_and_quit
pattern = options[:pattern] || show_help_and_quit
raise 'No 数 found. Please check the pattern.' unless pattern.include? '数'
range_str = options[:range] || show_help_and_quit
output_dir = options[:output] || File.basename(html_path, '.*')
doc = Nokogiri::HTML(open(html_path))
range = eval(range_str)
range.each do |i|
xpath = pattern.gsub('数', i.to_s)
nodes = doc.xpath(xpath)
# 各ノードを処理
nodes.each do |node|
html = node.inner_html
html.gsub!(/\R|\t/, ' ') # remove any existing newlines or tabs
html.gsub!(/<(h[1-6]|p|li|dd)/, "\n\\0") # add a newline before each heading and paragraph
html.gsub!(%r{</(h[1-6]|p|li|dd)>}, "\\0\n") # add a newline after each ending heading and paragraph tag
text = Nokogiri::HTML(html).text # convert back to text, which removes the HTML tags
file_name = xpath.gsub(/[^0-9A-Za-z_]/, '')
FileUtils.mkdir_p(output_dir)
File.open("#{output_dir}/#{file_name}.txt", 'a') do |f| # 指定されたディレクトリにファイルを保存
f.puts text
end
end
end
こういうミニスクリプトってどうやって管理するのがいいんでしょうかね。実行権限与えて直接 /usr/local/bin
に突っ込んでおけばいいのかしらん。
③ファイルの抽出
Usage: kirinuki.rb [options]
Example: ruby kirinuki.rb -f 'path/to/your.html' -p '//*[@id="sec数"]' -r '1..12'
-f, --file HTML_PATH HTML file path
-p, --pattern PATTERN Pattern
-r, --range RANGE Range
-o, --output OUTPUT_DIR Output directory
Exampleを参考にして、先程作ったツールを実行します。「数」のところが、rangeのイテレータの各要素に置き換わる仕組みになっています。range
は eval
で評価されるので、いろいろな応用ができます。セキュリティの観点から eval
はなるべく使わない方がいいと言われていますが、今回はローカルのファイルを変換するだけなので問題ないでしょう。
④ファイルのToken数の確認
いろいろな方法があると思いますが、私はなるべくUnixのコマンドを使う方法を好みます。
ChatGPTを使って翻訳する
ここでは、自作のchatgpt-cli を使います。それなりに便利なツールですが、万人に向けて作られていないので使いたい人だけ使ってね、という感じですね。ここでは基本の機能のみを使います。他のChatGPT向けコマンドラインツールでも同じことができるはずです。
まずは、翻訳用のプロンプトのテンプレートを作ります。
次の論文のアブストラクトを読んでください。
# ここにアブストやサマリーをコピペする
読み終わったら、以下のセクションを翻訳してください。わかりやすく平易な文章でお願いします。
翻訳された文章だけ回答してください。
---
上のテンプレートはかなり改善の余地があるでしょう。たとえば、専門用語では英文をカッコで併記させたりするといいかもしれません。
これで、cat prompt.txt idsec1.txt
とすると、プロンプト、翻訳対象の英文、の順番で出力されます。これを標準入力から chatgpt-cli
に投げます。
cat prompt.txt idsec1.txt | chatgpt -M gpt-4 > idsec1_ja.txt
さらに、連番をまわすシェルスクリプトを書きます。
seq 1 12 | xargs -t -I{} sh -c 'cat prompt.txt idsec{}.txt | chatgpt -M gpt-4 > idsec{}_ja.txt'
あとはひたすら待っていれば翻訳されたテキストファイルが生成されます。
この工程はかなり時間がかかりますので、気長に待ちましょう。
論文の再構成をどうするか?
pandoc?
終わりに
早ければ数ヶ月、遅くても1年後には、論文全体がChatGPTのトークンに乗るようになるでしょう。なので、ここに書いてあるような論文を分割して、トークン数に乗せる仕組みは早晩いらなくなるでしょう。けれども、現時点ではトークン数に限界があるので、こんな感じで工夫をする必要があります。
いずれは便利なツールができて、ボタン一個で簡単に翻訳できるようになるんでしょうね。
この記事は以上です。