醋醋百科网

Good Luck To You!

Ubuntu 22.04安装MySQL : Qwen2.5 模型对话数据收集与微调教程


1 安装 MySQL

首先来到(安装)根目录下,开启终端

1.1 更新和升级软件包

首先,更新本地软件包索引数据库并升级所有已安装的软件包到最新版本。

# 更新本地软件包索引数据库以及升级所有已安装的软件包到最新版本

apt-get update && apt-get upgrade

在此输入 y 执行更新命令

注意:这两个命令通常一起使用,通过&&操作符连接,确保只有在 apt-get update 成功执行后,才会执行 apt-get upgrade。

1.2 安装 MySQL 服务器

接下来,安装 MySQL 服务器软件包及其所有必要的依赖项。

# 安装MySQL服务器软件包  

apt-get install mysql-server

在此输入 y 执行安装命令

等待安装完成

1.3 检查 MySQL 服务状态

使用以下命令检查 MySQL 服务的当前状态,以确认它是否正在运行。

# 检查MySQL服务的状态  

service mysql status

MySQL 初次安装,服务处于停止运行状态。

1.4 启动 MySQL 服务

如果 MySQL 服务未运行,可以使用以下命令启动它。

# 启动MySQL服务  

service mysql start

再次查看 MySQL 服务状态,已经正常启动

1.5 确认是否成功开启 MySQL 服务

# 确认是否启动成功,在LISTEN状态下,启动成功

netstat -tap | grep mysql


1.6 重启 MySQL 服务

在更新 MySQL 服务器软件或更改其配置文件后,可以使用以下命令重启 MySQL 服务,以确保所有的更改都生效。

# 重启MySQL服务  

service mysql restart

这个命令会先尝试停止 MySQL 服务(如果它正在运行),然后再次启动它。

1.7 停止 MySQL 服务

如果需要停止 MySQL 服务,可以使用以下命令。

# 停止MySQL服务  

service mysql stop

停止服务后,MySQL 将不再接受新的连接,并且当前正在处理的连接可能会被中断。

2 运行 MySQL

2.1 进入 MySQL 的命令行

mysql

2.2 设置密码

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';

2.3 退出客户端

exit;

2.4 使用密码进入 MySQL 命令行

mysql -u root -p123456

2.5 设置远程登陆

  • 选择数据库
use mysql;
  • 修改 root 的 host 为 % 即无论在哪台主机上都能够登陆
update user set host='%' where user='root' and host='localhost';
  • 刷新数据库
flush privileges;
  • 通过命令查看是否对该用户授权成功
SELECT user,host FROM mysql.user;

修改之前的图片

修改之后的图片

2.6 退出客户端

exit;

3 修改配置

vim 打开后,如下图,需要按照图示添加命令、修改设置权限

(vim 编辑器基础使用: i 进入编辑 esc 退出编辑 :wq 保存退出)

3.1 进入配置文件

vim /etc/mysql/mysql.conf.d/mysqld.cnf

3.2 修改 bind-address

bind-address = 0.0.0.0

3.3 解决中文乱码

添加命令

character_set_server=utf8

3.4 保存退出,重启服务

在更新 MySQL 服务器软件或更改其配置文件后,可以使用以下命令重启 MySQL 服务,以确保所有的更改都生效。

# 重启MySQL服务  

service mysql restart

4 Mysql 远程连接测试

4.1 Windows 环境下打开算家云 SSH 隧道工具

4.2 在算家云 SSH 隧道工具选择实例和设置端口号为 3306(MySQL默认端口号,可在配置文件进行修改)

4.3 Windows 环境下打开 Navicat 并进行连接测试

4.4 测试数据库远程功能是否正常

select a.User,a.Host from user a;

5 大模型 Qwen2.5 微调步骤

5.1 从github 仓库克隆项目

  • 克隆存储库:
#拉取代码
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git

出现以上页面即是克隆项目成功!

请注意,如果 git clone https://github.com/hiyouga/LLaMA-Factory.git 这个链接不存在或者无效,git clone 命令将不会成功克隆项目,并且会报错。确保链接是有效的,并且您有足够的权限访问该存储库。

5.2 安装模型依赖库

  • 切换到项目目录、安装依赖
#切换到LLaMA-Factory根目录
cd LLaMA-Factory

#安装项目依赖
pip install -e ".[torch,metrics]"

等待安装完成

5.3 下载需要微调的模型

  • Git 下载
  • 请确保 lfs 已经被正确安装
git lfs install

git clone https://www.modelscope.cn/Qwen/Qwen2.5-0.5B-Instruct.git Qwen/Qwen2.5-0.5B-Instruct

5.4 启动 webui.py 文件

注意这里需要在 LLaMA-Factory 的根目录启动

# 启动 webui.py 文件
python src/webui.py

这个错误信息表明在尝试导入 PyTorch 时遇到了问题,具体是在加载 CUDA 相关的库 libcusparse.so.12 时因为缺少一个符号(__nvJitLinkComplete_12_4)而失败。这通常意味着你的 CUDA 或相关的 NVIDIA 驱动版本与 PyTorch 预期的版本不匹配。

要解决这个问题,你可以尝试以下几个步骤:

  1. 检查 CUDA 和 NVIDIA 驱动版本
    确保你的 CUDA 和 NVIDIA 驱动程序版本与你的 PyTorch 版本兼容。你可以在 NVIDIA 的官方网站上查找支持的版本。
  2. 更新或降级 CUDA 和 NVIDIA 驱动
    如果发现版本不兼容,你可能需要更新或降级你的 CUDA 工具包和 NVIDIA 驱动程序。这通常涉及到下载并安装新的版本,或卸载当前版本后安装旧版本。
  3. 检查 PyTorch 版本
    确保你安装的 PyTorch 版本是为你的 CUDA 版本构建的。例如,如果你使用的是 CUDA 11.x,你应该安装为 CUDA 11.x 构建的 PyTorch。
  4. 使用 Docker 或虚拟环境
    为了避免系统级别的依赖冲突,可以考虑使用 Docker 或创建一个干净的虚拟环境来安装和测试你的 PyTorch 和 CUDA 配置。
  5. 重新安装 PyTorch
    在确认 CUDA 和 NVIDIA 驱动版本正确后,尝试重新安装 PyTorch。你可以使用如下命令(以 CUDA 12.1 为例):
pip install torch==2.4.0 torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu121

重新启动 webui.py 文件

# 启动 webui.py 文件
python src/webui.py

需要设置 Gradio 服务器名称和端口

# 设置 Gradio 服务器名称和端口
export GRADIO_SERVER_NAME=0.0.0.0
export GRADIO_SERVER_PORT=8080

# 启动 webui.py 文件
python src/webui.py

启动端口后就可以访问微调页面了页面如下:

5.5 微调页面操作步骤

5.5.1 语言切换

5.5.2 选择微调模型

5.5.3 加载本地模型的文件路径

5.5.4 准备数据集

  • 复制以下路径进入 算家云文件管理 页面,并打开 identity.json 文件
/LLaMA-Factory/data/
  • 按照以下数据格式进行数据替换

5.5.5 选择数据

5.5.6 开始微调模型

出现以上问题,需要安装 deepspeed 依赖

# 安装 deepspeed 依赖
pip3 install deepspeed

等待安装完成

再次启动 webui.py 文件,开始微调模型

# 启动 webui.py 文件
python src/webui.py

5.5.7 微调过程展示

  • web 页面
  • 命令行

5.5.8 训练完成

5.5.9 模型验证

  • 选择模型检查点
  • 选择数据集
  • 开始执行验证模型
  • 等待执行完成

5.5.10 模型加载

  • 加载模型检查点
  • 输入文本,进行对话
  • 验证模型对话

5.5.11 模型合并

  • 加载保存导出模型的文件夹路径
  • web 完成页面
  • 命令行完成页面

6 大模型 Qwen2.5 微调调用

6.1 结束当前运行(按键盘上的 Ctrl + C)

6.2 从github 仓库克隆项目

  • 克隆存储库:
#拉取代码
git clone https://github.com/QwenLM/Qwen2.5.git

出现以上页面即是克隆项目成功!

请注意,如果 git clone https://github.com/QwenLM/Qwen2.5.git 这个链接不存在或者无效,git clone 命令将不会成功克隆项目,并且会报错。确保链接是有效的,并且您有足够的权限访问该存储库。

6.3 修改微调后保存的模型、IP以及端口

vim Qwen2.5/examples/demo/web_demo.py

6.4 启动 webui.py 文件

# 启动 webui.py 文件
python Qwen2.5/examples/demo/web_demo.py

6.5 访问端口,进行模型测试

测试结果如下

7 编辑 webui.py 文件连接 MySQL 数据库

7.1 创建数据库连接函数

在 create_connection函数中,通过传递主机名、用户名、密码和数据库名称来创建一个MySQL数据库连接。

def create_connection(host_name, user_name, user_password, db_name):
    connection = None
    try:
        connection = mysql.connector.connect(
            host=host_name,
            user=user_name,
            passwd=user_password,
            database=db_name,
            charset='utf8mb4',
            port=3306
        )
        print("Connection to MySQL DB successful")
    except Error as e:
        print(f"The error '{e}' occurred")
    return connection

7.2 创建数据库函数

如果数据库不存在,使用 create_database函数创建一个新的数据库。

def create_database(connection, db_name):
    cursor = connection.cursor()
    try:
        cursor.execute(f"CREATE DATABASE IF NOT EXISTS {db_name}")
        print(f"Database {db_name} created successfully")
    except Error as e:
        print(f"The error '{e}' occurred")

7.3 创建数据表函数

在数据库中创建一个表,用于存储用户的提问和AI的回答。如果表已存在,则不会重复创建。

def create_table(connection, table_name):
    cursor = connection.cursor()
    try:
        cursor.execute(f"""
        CREATE TABLE IF NOT EXISTS {table_name} (
            id INT AUTO_INCREMENT PRIMARY KEY,
            user_message TEXT NOT NULL,
            ai_response TEXT NOT NULL,
            timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
        """)
        print(f"Table {table_name} created successfully")
    except Error as e:
        print(f"The error '{e}' occurred")

7.4 创建数据库和数据表

接下来,在 _launch_demo 函数中,使用了 create_connection 函数创建数据库连接,并调用 create_database 和 create_table 函数来确保所需的数据库和表存在。这些函数执行 SQL 语句以创建数据库和表,同时处理可能出现的任何错误。

# 创建数据库连接
connection = create_connection('localhost', 'root', '123456', 'Qwen2_5_db')

# 创建数据库和数据表
if connection.is_connected():
    create_database(connection, 'Qwen2_5_db')
    create_table(connection, 'Qwen2_5_tb')

7.5 插入对话记录

当用户与AI进行交互后,AI的回答会被记录下来,并且这个记录会被插入到之前创建的数据表中。这一步是在 predict函数内部完成的,当AI生成了最终的响应后,会调用 execute_query函数执行SQL插入语句。

insert_query = f"""
INSERT INTO Qwen2_5_tb (user_message, ai_response, timestamp)
VALUES ('{_query.replace("'", "''")}', '{full_response.replace("'", "''")}', NOW() + INTERVAL 8 HOUR)
"""
execute_query(connection, insert_query)

这里需要注意的是,由于SQL语句中可能包含单引号,因此在插入数据之前,需要对单引号进行转义处理,即使用 replace("'", "''")方法将单引号替换为两个单引号。

7.5 执行SQL查询

execute_query函数负责执行SQL语句并提交更改。

def execute_query(connection, query):
    cursor = connection.cursor()
    try:
        cursor.execute(query)
        connection.commit()
        print("Query executed successfully")
    except Error as e:
        print(f"Theerror '{e}' occurred")

7.6 关闭数据库连接

最后,在 Gradio 接口启动之后,如果数据库连接仍然处于打开状态,则会在 _launch_demo 函数结束前关闭它。

if connection.is_connected():
    connection.close()
    print("MySQL connection is closed")

这样,每次用户与模型交互时,对话记录都会被安全地存储在数据库中,为后续的数据分析或审计提供了便利。同时,通过合理的错误处理机制,可以保证即使发生异常也能保持系统的健壮性。

7.8 融入全部 MySQL 代码到 webui.py 文件

# Copyright (c) Alibaba Cloud.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.

from argparse import ArgumentParser
from threading import Thread
import gradio as gr
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
import mysql.connector
from mysql.connector import Error

# 默认检查点路径
DEFAULT_CKPT_PATH = '/LLaMA-Factory/Qwen/Qwen2.5-0.5B-Instruct-20241025-1/'

# 解析命令行参数
def _get_args():
    parser = ArgumentParser()
    parser.add_argument("-c", "--checkpoint-path", type=str, default=DEFAULT_CKPT_PATH,
                        help="Checkpoint name or path, default to %(default)r")
    parser.add_argument("--cpu-only", action="store_true", help="Run demo with CPU only")
    parser.add_argument("--share", action="store_true", default=False,
                        help="Create a publicly shareable link for the interface.")
    parser.add_argument("--inbrowser", action="store_true", default=False,
                        help="Automatically launch the interface in a new tab on the default browser.")
    parser.add_argument("--server-port", type=int, default=8080,
                        help="Demo server port.")
    parser.add_argument("--server-name", type=str, default="0.0.0.0",
                        help="Demo server name.")
    return parser.parse_args()

# 加载模型和分词器
def _load_model_tokenizer(args):
    tokenizer = AutoTokenizer.from_pretrained(
        args.checkpoint_path, resume_download=True,
    )

    if args.cpu_only:
        device_map = "cpu"
    else:
        device_map = "auto"

    model = AutoModelForCausalLM.from_pretrained(
        args.checkpoint_path,
        torch_dtype="auto",
        device_map=device_map,
        resume_download=True,
    ).eval()
    model.generation_config.max_new_tokens = 4096   # 设置最大生成令牌数
    return model, tokenizer

# 创建数据库连接
def create_connection(host_name, user_name, user_password, db_name):
    connection = None
    try:
        connection = mysql.connector.connect(
            host=host_name,
            user=user_name,
            passwd=user_password,
            database=db_name,
            charset='utf8mb4',
            port=3306
        )
        print("Connection to MySQL DB successful")
    except Error as e:
        print(f"The error '{e}' occurred")
    return connection

# 创建数据库
def create_database(connection, db_name):
    cursor = connection.cursor()
    try:
        cursor.execute(f"CREATE DATABASE IF NOT EXISTS {db_name}")
        print(f"Database {db_name} created successfully")
    except Error as e:
        print(f"The error '{e}' occurred")

# 创建数据表
def create_table(connection, table_name):
    cursor = connection.cursor()
    try:
        cursor.execute(f"""
        CREATE TABLE IF NOT EXISTS {table_name} (
            id INT AUTO_INCREMENT PRIMARY KEY,
            user_message TEXT NOT NULL,
            ai_response TEXT NOT NULL,
            timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
        """)
        print(f"Table {table_name} created successfully")
    except Error as e:
        print(f"The error '{e}' occurred")

# 执行SQL查询
def execute_query(connection, query):
    cursor = connection.cursor()
    try:
        cursor.execute(query)
        connection.commit()
        print("Query executed successfully")
    except Error as e:
        print(f"The error '{e}' occurred")

# 聊天流生成器
def _chat_stream(model, tokenizer, query, history):
    conversation = [
        {'role': 'system', 'content': 'You are a helpful assistant.'},
    ]
    for query_h, response_h in history:
        conversation.append({'role': 'user', 'content': query_h})
        conversation.append({'role': 'assistant', 'content': response_h})
    conversation.append({'role': 'user', 'content': query})
    inputs = tokenizer.apply_chat_template(
        conversation,
        add_generation_prompt=True,
        return_tensors='pt',
    )
    inputs = inputs.to(model.device)
    streamer = TextIteratorStreamer(tokenizer=tokenizer, skip_prompt=True, timeout=60.0, skip_special_tokens=True)
    generation_kwargs = dict(
        input_ids=inputs,
        streamer=streamer,
    )
    thread = Thread(target=model.generate, kwargs=generation_kwargs)
    thread.start()

    response = ""
    for new_text in streamer:
        response += new_text
        yield response

    return response

# 垃圾回收
def _gc():
    import gc
    gc.collect()
    if torch.cuda.is_available():
        torch.cuda.empty_cache()

# 启动Gradio界面
def _launch_demo(args, model, tokenizer):
    # 创建数据库连接
    connection = create_connection('localhost', 'root', '123456', 'Qwen2_5_db')

    # 创建数据库和数据表
    if connection.is_connected():
        create_database(connection, 'Qwen2_5_db')
        create_table(connection, 'Qwen2_5_tb')

    def predict(_query, _chatbot, _task_history, use_history=True):
        print(f"User: {_query}")
        _chatbot.append((_query, ""))
        full_response = ""
        history = _task_history if use_history else []
        response_generator = _chat_stream(model, tokenizer, _query, history=history)
        for response in response_generator:
            _chatbot[-1] = (_query, response)
            yield _chatbot
            full_response = response

        print(f"History: {_task_history}")
        if use_history:
            _task_history.append((_query, full_response))
        print(f"Qwen2-Instruct: {full_response}")

        # 将对话保存到数据库
        insert_query = f"""
        INSERT INTO Qwen2_5_tb (user_message, ai_response, timestamp)
        VALUES ('{_query.replace("'", "''")}', '{full_response.replace("'", "''")}', NOW() + INTERVAL 8 HOUR)
        """
        execute_query(connection, insert_query)

    def regenerate(_chatbot, _task_history):
        if not _task_history:
            yield _chatbot
            return
        item = _task_history.pop(-1)
        _chatbot.pop(-1)
        yield from predict(item[0], _chatbot, _task_history)

    def reset_user_input():
        return gr.update(value="")

    def reset_state(_chatbot, _task_history):
        _task_history.clear()
        _chatbot.clear()
        _gc()
        return _chatbot

    with gr.Blocks() as demo:
        # gr.Markdown("""<center><font size=8>Qwen2.5-7B-Instruct-1018-1 帮助手册10月18日微调测试</center>""")
        gr.Markdown("""<center><font size=7> 算家计算 Chatbot</center>""")
        gr.Markdown("""<center><font size=4> A streamlit chatbot powered by SuanJiayun</center>""")
        gr.Markdown("""<center><font size=5>Qwen2.5-3B-Instruc 帮助手册、身份、国庆客户问题、模型缺失依赖包 10月24日微调测试</center>""")
        chatbot = gr.Chatbot(label='Qwen2.5-7B-Instruct', elem_classes="control-height")
        query = gr.Textbox(lines=2, label='Input')
        task_history = gr.State([])

        with gr.Row():
            empty_btn = gr.Button(" Submit (发送)")
            #submit_btn = gr.Button(" Submit (发送)")
            #regen_btn = gr.Button(" Regenerate (重试)")

        #submit_btn.click(predict, [query, chatbot, task_history, gr.Checkbox(True)], [chatbot], show_progress=True)
        #submit_btn.click(reset_user_input, [], [query])
        empty_btn.click(predict, [query, chatbot, task_history, gr.Checkbox(False)], [chatbot], show_progress=True)
        empty_btn.click(reset_user_input, [], [query])
        empty_btn.click(reset_state, [chatbot, task_history], outputs=[chatbot], show_progress=True)
        #regen_btn.click(regenerate, [chatbot, task_history], [chatbot], show_progress=True)

        gr.Markdown("""\
        <font size=2>Note: This demo is governed by the original license of Qwen2.5. \
        We strongly advise users not to knowingly generate or allow others to knowingly generate harmful content, \
        including hate speech, violence, pornography, deception, etc. \
        (注:本演示受 Qwen2.5 的许可协议限制。我们强烈建议,用户不应传播及不应允许他人传播以下内容,\
        包括但不限于仇恨言论、暴力、色情、欺诈相关的有害信息。)""")

    demo.queue().launch(
        share=args.share,
        inbrowser=args.inbrowser,
        server_port=args.server_port,
        server_name=args.server_name,
    )
    if connection.is_connected():
        connection.close()
        print("MySQL connection is closed")

# 主函数
def main():
    args = _get_args()
    model, tokenizer = _load_model_tokenizer(args)
    _launch_demo(args, model, tokenizer)

if __name__ == '__main__':
    main()

8 测试 MySQL 是否正常连接到对话过程

8.1 启动 webui.py 文件

# 启动 webui.py 文件
python Qwen2.5/examples/demo/web_demo.py

遇到 ModuleNotFoundError: No module named 'mysql' 错误意味着你的环境中没有安装 mysql-connector-python 这个包。要解决这个问题,你需要先安装这个包。

  • 安装 mysql-connector-python

打开终端或命令提示符,运行以下命令:

pip install mysql-connector-python

这将会下载并安装 mysql-connector-python 包及其依赖项。

再次启动 webui.py 文件

# 启动 webui.py 文件
python Qwen2.5/examples/demo/web_demo.py

出现以上报错,需要先创建数据库(命令行或者Navicat里面的查询都可以)

再次启动 webui.py 文件

# 启动 webui.py 文件
python Qwen2.5/examples/demo/web_demo.py

8.2 访问端口,进行模型测试

  • Gradio 测试结果如下
  • 命令行测试结果如下
  • Navicat 测试结果如下

到此,Ubuntu 22.04 安装 MySql 进行 Qwen2.5 模型微调的对话数据收集到此就结束了。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言