如何通过 Java ProcessBuilder 在 python 脚本中使用包(例如转换器)

How can I use a package (such as transformers) in python script through Java ProcessBuilder

为了连接管道的 Java 和 Python 部分,我正在尝试不同的方法。目前我正在 Java:

中使用以下代码尝试 ProcessBuilder 方法
import java.io.*;
import java.util.*;

public class Tryout {
    public static void main(String []args) {
        try {
            var processBuilder = new ProcessBuilder("/usr/bin/python3", "tryout.py", "example string for testing purposes");
            processBuilder.redirectErrorStream(true);
            var process = processBuilder.start();
            process.waitFor();
            System.out.println(process);
            try (var reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()))) {

                String line;

                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
            }
        }
        catch(IOException e){
            System.out.println(e.getMessage());
        }
        catch(InterruptedException e){
            System.out.println(e.getMessage());
        }
    }
}

以及 python 的代码:

from transformers import BertTokenizer
import sys


print("hello from python!")
input_string = sys.argv[1]
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
tokens = tokenizer(input_string, padding='max_length', max_length=512, truncation=True, return_tensors="np")
print(list(tokens['input_ids'][0]))
print(list(tokens['attention_mask'][0]))

但是,这给了我错误:ModuleNotFoundError: No module named 'transformers'。 在您询问之前,转换器包已安装,并且 python 脚本 运行 在从命令行调用时正常。 我的问题是:如何在 JVM 中包含这些模块?

我不完全理解 ProcessBuilder 的技术细节,并假设它会 运行 在命令行中使用我的本地 python 环境,但显然情况并非如此。

确保用于 JVM 启动的 PYTHONPATH 与从 shell 启动它的 python 相同。这将确保 python 运行 时使用的环境作为 Java 的 sub-process 将与 运行 时直接来自 shell 的环境匹配] / 终端机。

编辑

对于有同样问题的其他人,这里有一些方法可以检查或设置 Java -> Python 调用的 PYTHONPATH。默认情况下 Java 传递从它自己的环境变量中使用的值:

System.out.println("getenv().PYTHONPATH="+System.getenv("PYTHONPATH"));

或者为 ProcessBuilder 启动设置 PYTHONPATH:

String pypath = List.of(Path.of("somedir"), Path.of("anotherdir"))
       .stream().map(Path::toAbsolutePath).map(Path::toString)
       .collect(Collectors.joining(File.pathSeparator));
pb.environment().put("PYTHONPATH", pypath);
System.out.println("environment().PYTHONPATH="+pb.environment().get("PYTHONPATH"));

检查现有 python 脚本中使用的值:

# import os
print("PYTHONPATH", os.getenv('PYTHONPATH'))