Published on

Jupyter Notebook 基础

Authors
  • avatar
    Name
    游戏人生
    Twitter

环境安装及配置

安装 python

  brew install python3

安装 pip

  sudo easy_install pip

安装 Jupyter Notebook

  pip install notebook

安装 Deno

  curl -fsSL https://deno.land/install.sh | sh

配置环境变量(MacOS)

Deno 安装完成后,在 ~/.bash_profile 中添加以下内容:xxxxxx 为当前用户的目录

  export DENO_INSTALL="/Users/xxxxxx/.deno"
  export PATH="$DENO_INSTALL/bin:$PATH"

如果终端使用 zsh,则修改 ~/.zshrc 文件,加入如下内容:

  source ~/.bash_profile

配置完成后,重启终端,执行 deno --version 命令,如果出现版本信息,则表示安装成功。

配置 Jupyter Notebook

使用 Deno 为 Jupyter Notebook 配置 kernel:

  deno jupyter --unstable --install

验证是否配置成功:

  deno jupyter --unstable

出现 Deno kernel already installed 即表示配置成功。

安装完成后,启动 notebook:

  jupyter notebook

启动成功后,在浏览器中访问 http://localhost:8888/tree 就可以看到 Jupyter Notebook 的界面。

获取模型

获取线上模型

以阿里云灵积大模型为例,线上申请 模型。

模型申请成功后,即可本地访问线上模型,做测试。

获取本地模型

因为线上模型一般都需要收费,为节约成本,也可以使用本地模型进行测试,但是本地模型对设备资源要求较高,可视情况安装对应的模型。

本地模型平台 mac 系统推荐 Ollama,win 系统推荐 LM Studio,进入对应的官网下载即可, 安装成功后启动 app,即可在 http://localhost:11434 启动一个 llm 的服务。

以 Ollama 为例,在 gitHub 中可以查找其支持的模型。 Ollama 服务启动后,在控制台中执行如下命令下载对应的模型到本地:

  ollama run modelName

链接模型

在 notebook 界面中,创建项目文件夹,用于存放测试代码,测试代码是基于 Deno 和 js 实现。

配置 deno 依赖

Deno 是直接远程拉取依赖,且自带缓存机制,不需要本地安装,只需要配置依赖项即可。 模型的链接依赖于 langchain.js。在 Deno 使用 dotenv 来加载环境变量。

在项目根目录下,新建 deno.json,加入以下内容:

  {
    "imports": {
      "lodash": "npm:/lodash@4.17.21",
      "dotenv": "https://deno.land/std@0.220.0/dotenv/mod.ts",
      "langchain": "npm:/langchain@0.2.3",
      "langchain/": "npm:/langchain@0.2.3/",
      "@langchain/openai": "npm:/@langchain/openai@0.0.22",
      "@langchain/openai/": "npm:/@langchain/openai@0.0.22/",
      "@langchain/core": "npm:/@langchain/core@0.1.48",
      "@langchain/core/": "npm:/@langchain/core@0.1.48/",
      "zod": "npm:/zod",
      "pdf-parse": "npm:/pdf-parse/lib/pdf-parse.js",
      "ignore": "npm:/ignore",
      "cheerio": "npm:/cheerio",
      "vectordb": "npm:/vectordb",
      "@lancedb/lancedb": "npm:/@lancedb/lancedb",
      "faiss-node": "npm:/faiss-node",
      "openai": "npm:/openai",
      "@langchain/community": "npm:/@langchain/community@0.2.2",
      "@langchain/community/": "npm:/@langchain/community@0.2.2/",
      "zod-to-json-schema": "npm:/zod-to-json-schema"
    },
    "deno.enable": true
  }

链接线上模型

在项目目录下新建 demo.ipynb 文件,在 notebook 中打开此文件,右侧内核选择 Deno。

目录下新建 .env 文件,加入模型的 API(在对应的控制台获取):

  ALIBABA_API_KEY=xxx

在 ipynb 文件中,首先加载环境变量,由于 langchain.js 是为 node 设计,因此会默认从 process.env 中进行读取。执行以下命令, 将环境变量加载到 process.env 中:

  import { load } from "dotenv";
  const env = await load();

  const process = {
    env,
  };

链接模型,并进行问询,参考自langchain.js

  import { ChatAlibabaTongyi } from "@langchain/community/chat_models/alibaba_tongyi";
  // import { ChatBaiduWenxin } from "@langchain/community/chat_models/baiduwenxin"; // 百度千帆模型
  import { HumanMessage } from "@langchain/core/messages";

  const model = new ChatAlibabaTongyi({
    model: "qwen-turbo", // Available models: qwen-turbo, qwen-plus, qwen-max
    temperature: 1,
  });

  // 百度千帆模型 ERNIE-Lite-8K、ERNIE-Lite-8K-0922、ERNIE-Tiny-8K、ERNIE-Speed-128K、ERNIE-Speed-8K、ERNIE Speed-AppBuilder 已免费
  // const model = new ChatBaiduWenxin({
  //   model: "ERNIE-Speed-8K", // ERNIE-Bot,ERNIE-Bot-turbo,ERNIE-Bot-4,ERNIE-Speed-8K,ERNIE-Speed-128K,ERNIE-4.0-8K, ERNIE-4.0-8K-Preview,ERNIE-3.5-8K,ERNIE-3.5-8K-Preview,ERNIE-Lite-8K,ERNIE-Tiny-8K,ERNIE-Character-8K, ERNIE Speed-AppBuilder
  //   temperature: 1,
  // });

  const stream = await model.invoke([
    new HumanMessage("讲个笑话"),
  ]);

  console.log(stream);

返回内容格式如下:

  AIMessage {
    lc_serializable: true,
    lc_kwargs: {
      content: "为什么袜子总是只丢一只?因为丢两只根本就不会发现。",
      tool_calls: [],
      invalid_tool_calls: [],
      additional_kwargs: {},
      response_metadata: {}
    },
    lc_namespace: [ "langchain_core", "messages" ],
    content: "为什么袜子总是只丢一只?因为丢两只根本就不会发现。",
    name: undefined,
    additional_kwargs: {},
    response_metadata: {
      tokenUsage: { promptTokens: 11, completionTokens: 15, totalTokens: 26 }
    },
    tool_calls: [],
    invalid_tool_calls: []
  }

使用 StringOutputParser 对输出的内容进行处理,处理后只输出普通文本:

  import { ChatAlibabaTongyi } from "@langchain/community/chat_models/alibaba_tongyi";
  import { HumanMessage } from "@langchain/core/messages";
  import { StringOutputParser } from "@langchain/core/output_parsers";

  const model = new ChatAlibabaTongyi({
    model: "qwen-turbo", // Available models: qwen-turbo, qwen-plus, qwen-max
    temperature: 1,
    maxRetries: 0, // 出错重试次数
  });

  const outputPrase = new StringOutputParser();
  const simpleChain = model.pipe(outputPrase);

  const stream = await simpleChain.invoke([
    new HumanMessage("你是谁"),
    new HumanMessage("讲个笑话"),
  ]);

  console.log(stream);

使用 withFallbacks 增加 fallBack 保证在环境差的情况下也有输出:

  import { ChatAlibabaTongyi } from "@langchain/community/chat_models/alibaba_tongyi";
  import { HumanMessage } from "@langchain/core/messages";
  import { StringOutputParser } from "@langchain/core/output_parsers";

  const model = new ChatAlibabaTongyi({
    model: "qwen-turbo", // Available models: qwen-turbo, qwen-plus, qwen-max
    temperature: 1,
    maxRetries: 0, // 出错重试次数
  });

  const model2 = new ChatAlibabaTongyi({
    model: "qwen-plus", // Available models: qwen-turbo, qwen-plus, qwen-max
    temperature: 1,
    maxRetries: 0, // 出错重试次数
  });

  const fallbackModl = model.withFallbacks({
    fallbacks: [model2]
  })

  const outputPrase = new StringOutputParser();
  const simpleChain = fallbackModl.pipe(outputPrase);


  const stream = await simpleChain.invoke([
    new HumanMessage("你是谁"),
    new HumanMessage("讲个笑话"),
  ]);

  console.log(stream);

链接本地模型

链接本地模型需要使用 ollama,本地启动 Ollama 服务,baseUrl 指向 http://localhost:11434:

参考自langchain.js

  import { Ollama } from "@langchain/community/llms/ollama";
  import { HumanMessage } from "@langchain/core/messages";
  import { StringOutputParser } from "@langchain/core/output_parsers";

  const ollama = new Ollama({
    baseUrl: "http://localhost:11434", 
    model: "qwen:7b", 
  });

  const outputPrase = new StringOutputParser();

  const simpleChain = ollama.pipe(outputPrase);
  const stream = await simpleChain.invoke([
      new HumanMessage("讲个笑话"),
  ]);

  console.log(stream);