使用780M核显借助LM Studio部署QWQ32B

使用780M核显借助LM Studio部署QWQ32B

前言

之前已经部署了DeepSeek r1:14b小模型:

Win10环境借助OLLAMA本地部署Deep Seek实现一个简单的聊天机器人:https://lizhiyong.blog.csdn.net/article/details/145505686

Win10环境使用ChatBox集成Deep Seek解锁更多玩法:https://lizhiyong.blog.csdn.net/article/details/145524481

Win10环境借助DockerDesktop部署Open web UI集成DeepSeek:https://lizhiyong.blog.csdn.net/article/details/145582453

Win10环境使用Dockerdesktop部署Dify集成Deepseek:https://lizhiyong.blog.csdn.net/article/details/145602366

Win10环境使用零讯ZeroNews内网穿透实现Deepseek对外服务:https://lizhiyong.blog.csdn.net/article/details/145716997

基本是借助Ollama部署的,对非英伟达显卡支持不是特别友好,受限于丽台RTX A4000显卡的16GB显存,并不能跑32B等稍大的模型。96GB魔改显存的RTX 4090价格3w软妹币也不是我等难民能承担的。考虑到还有个Zbook工作站,以及Vulkan llama.cpp (Windows)方式直接调用核显,笔者尝试APU方式运行,快慢是另一回事,先解决能不能跑的问题!!!

显然LM Studio就是个很好的软件。

在这里插入图片描述

小巧精悍的QWQ 32B据说可以跑赢满血 671b Deepseek了,当然要试试!!!

设备

惠普战99锐龙版,和之前一样:

在Centos7.9_2207安装CDH6.3.2:https://lizhiyong.blog.csdn.net/article/details/134433148

硬件关键参数
CPU7840hs 8C16T 3.8GHz
核显Radeon 780M
内存2 * 48GB 5600MT/s DDR5
硬盘PCIE4.0 4T

二手东在25年3月份新上市了单条64GB的新款DDR5显存,理论上可以组128GB显存了,但是毛衣战搞的严重缺货,一直抢不到,作罢了,先双48GB内存条狗着。共享GPU显存48GB也能凑合着跑一些稍大一点的小模型,别人3w的新款笔记本工作站能做的事情其实1w的老款工作站也能做!!!

安装LM Studio

https://lmstudio.ai/download

在这里插入图片描述

笔者使用0.3.14(build 5)

一直点下一步就行。

配置

中文及代理

在这里插入图片描述

可以看到LM Studio对新手异常友好!!!自己搭了代理就省的我等大数据学徒工科学上网自行去Huging Face找模型了!!!

模型存放路径

在这里插入图片描述

模型的存放路径也可以改!!!

在这里插入图片描述

最新的Gemma也已有了私有化部署版!!!晚一点可以玩一玩了!!!

调用核显

在这里插入图片描述

要配置GGUF的方式为Vulkan,不要用纯CPU算,主频低核少内存延迟高太吃亏。

尝试提问

Java代码,实现从cluster1集群的hive表db1.tb1同步数据到cluster2集群的hive表db2.tb2,数据量在亿级别

思考过程

在这里插入图片描述

思考了17min14s。

嗯,用户让我用Java编写一个程序,把Hive表从一个集群同步到另一个集群。数据量是亿级别的,我得考虑效率和性能问题。

首先,我应该确定同步的方式。通常有几种方法:比如导出文件然后导入,或者使用Sqoop之类的工具。不过用户要求用Java代码实现,可能需要直接操作Hive的API?

那我得想想怎么连接两个集群的Hive。可能需要用Hive JDBC驱动来执行查询和插入语句?对了,Hive有JDBC接口,可以这样操作。

然后数据量大,亿级别的数据,如果全表同步的话,直接用INSERT可能会有问题,比如内存不够或者速度慢。这时候是不是该分批次处理?比如分页查询,或者用MapReduce的方式?

另外,用户提到的是Hive表之间的同步,可能需要考虑分区的情况?不过问题里没提分区,暂时假设不分区。

首先,代码的结构大概是这样的:连接两个集群的Hive数据库,执行一个SELECT语句从cluster1的tb1读取数据,然后将这些数据插入到cluster2的tb2。但直接这样可能会有性能问题。

亿级的数据用JDBC逐行处理可能太慢了。或许应该用Hive自己的导入方式,比如导出为文本文件再加载到另一个集群?但用户想要Java代码实现,可能需要更自动化的方式?

或者使用Hive的INSERT OVERWRITE语句,直接通过Hive查询来执行同步?例如:

INSERT INTO TABLE db2.tb2 SELECT * FROM db1.tb1;

不过这需要两个集群之间的表结构一致,并且Hive版本支持跨集群查询。但通常两个集群可能不在同一个元数据服务器下,所以这样写可能不行。

那可能需要用Java代码先从源集群读取数据,然后批量插入到目标集群的表中?

比如步骤:

  1. 连接cluster1的Hive JDBC,执行SELECT * FROM db1.tb1;
  2. 获取结果集,逐行读取并保存为某种格式(比如对象);
  3. 将这些数据分批插入到cluster2的db2.tb2。

但问题在于亿级数据这样处理可能效率太低。JDBC逐条处理在大数据量时可能会很慢,甚至内存溢出?

有没有更好的方法?或者使用Hive的LOAD DATA命令加载文件数据?

或许可以采用中间存储的方式:比如把源表的数据导出为文本文件,然后上传到目标集群的HDFS,再用Hive的LOAD命令导入。这样可能更快。

那Java代码可以分为几个步骤:

  1. 连接cluster1的HiveServer2,执行查询并保存结果到本地临时文件; 或者直接在Hive中导出数据到HDFS路径,然后复制到另一个集群?

不过跨集群的数据同步,可能需要先将数据从源集群的HDFS拷贝到目标集群的HDFS,这需要两集群之间的网络允许。

另外,使用Java代码实现的话,可以:

步骤一:在source cluster执行hive命令导出数据: hdfs dfs -text /user/hive/warehouse/db1.db/tb1/* > /tmp/data.txt

但用Java代码怎么调用HDFS命令?可能需要运行shell命令或者调用Hadoop API。

步骤二:将导出的数据上传到目标集群的HDFS,比如使用distcp?

不过用户要求Java代码实现的话,可能希望全部流程自动化。或者是否可以编写一个MapReduce任务来处理?

但用户明确要Java代码,所以或许分两部分:

第一种方法:

  1. 使用JDBC读取源表的数据行,
  2. 将每批数据插入到目标表。

但是这样可能会遇到连接池的问题,以及网络延迟导致速度慢。对于亿级数据可能需要优化,比如批量执行insert语句。

例如,每次处理几百条记录作为一个批次,然后批量插入到目标表?

Hive的JDBC支持批量操作吗?比如用PreparedStatement.addBatch() ?

另一种方法是:

在源集群导出数据到文件(如CSV或文本),然后上传到目标集群的HDFS路径,再通过LOAD DATA命令加载到目标表。

这样可能更高效。代码可以分为三个步骤:

  1. 连接源Hive执行查询并保存为文本文件; 或者使用Hive的INSERT OVERWRITE DIRECTORY语句直接导出到HDFS路径?

比如: 在source集群运行: INSERT OVERWRITE LOCAL DIRECTORY ‘/tmp/export’ SELECT * FROM db1.tb1;

然后获取该本地目录的数据,再传输到目标集群。

不过用Java代码的话,可能需要:

  • 使用Hive的命令行工具执行查询并输出文件。例如通过Runtime.exec()执行Hive命令。 或者使用Hadoop API操作HDFS?

这可能会比较复杂,但可以更高效处理大数据量。

另外,用户要求的是Java实现,所以可能需要编写一个完整的流程代码,包括:

  1. 在source集群的Hive中导出数据到某个位置(比如HDFS路径);
  2. 将该数据从source集群的HDFS复制到target集群的HDFS;
  3. 在target集群的Hive表中加载这些文件。

可能需要使用Hadoop DistCp来复制HDFS之间的目录,这一步可以用Java调用DistCp类?

或者直接在代码里执行:

hdfs dfs -copyFromLocal 或者 distcp命令。

不过具体实现方式要视环境而定。

现在我得考虑如何编写具体的Java代码示例。可能用户希望看到一个简单的例子,虽然实际生产中可能需要更多错误处理和优化。

首先,对于JDBC的方法:

示例代码结构可能是这样:

  • 连接源Hive: Connection sourceConn = DriverManager.getConnection(“jdbc:hive2://cluster1:port/db1”, props);
  • 执行查询: Statement stmt = sourceConn.createStatement(); ResultSet rs = stmt.executeQuery(“SELECT * FROM tb1”);

然后读取rs的数据,并准备目标数据库的插入操作:

在目标集群连接后,用PreparedStatement逐条或批量插入。

但这样的问题在于,亿级数据可能会很慢,因为每次INSERT都可能需要网络往返和提交。Hive本身对大量INSERT处理效率不高?

或者可以使用multi-insert?不过Hive的JDBC是否支持批量操作?

或许更好的方式是生成一个HQL脚本,在目标集群执行:

比如: LOAD DATA INPATH ‘/path/to/data’ INTO TABLE db2.tb2;

这样只需要将数据文件复制到目标HDFS指定目录,再通过Hive命令加载。

所以可能需要这样的步骤:

代码流程:

  1. 在source集群上导出tb1的数据为文本文件,并存储在HDFS的某个位置; 例如: String exportCmd = “hive -e ‘INSERT OVERWRITE DIRECTORY ‘/tmp/export’ SELECT * FROM db1.tb1;’”; // 或者用JDBC执行该命令?

或者使用HiveContext在Java中执行这个查询并保存到路径。

这可能需要调用Hive的API,但可能比较复杂。或者更简单的方式是在Java代码里执行shell命令:

Runtime.getRuntime().exec(exportCmd);

不过跨平台问题需要注意。

  1. 将导出的数据目录从cluster1复制到cluster2的HDFS: 例如使用DistCp: String distcpCmd = “hadoop distcp hdfs://sourceCluster/tmp/export hdfs://targetCluster/path”; 执行该命令。
  2. 在目标集群上运行Hive命令将数据加载到tb2表: String loadCmd = “hive -e ‘LOAD DATA INPATH ‘/path/to/data’ INTO TABLE db2.tb2;’”;

不过这可能需要调整路径和权限。

但如何在Java中调用这些命令?可以用ProcessBuilder来执行外部进程。

这样,整个流程的Java代码会是一个脚本式的调用多个Hadoop/Hive命令。虽然效率较高,但需要处理命令的返回状态、错误等。

此外,如果用户希望更“纯”Java的方式,可能需要用Hive和HDFS的API来实现:

例如使用HiveMetaStoreClient, 或者直接操作HDFS文件系统。

不过这可能比较复杂,特别是对于非本地Hadoop环境。

现在我得考虑如何编写一个示例代码。可能以JDBC方法为主,但指出其局限性,并推荐更高效的方法。

另外需要注意表结构的一致性,比如确保db2.tb2的schema与源表一致,否则插入会出错。

同时,在处理大数据时,分批次或者使用并行处理可以提升速度,例如多线程读取和写入。

所以最终给出两种方案:一种是JDBC直接同步(适用于小数据量或测试),另一种是导出导入的批量方式更适合大表。

现在我需要写出一个示例代码,并解释其步骤。可能用户想要的是后者更高效的方式,因为数据量是亿级别。

因此,编写Java程序使用Hive命令和DistCp:

大致步骤:

  1. 导出源表到HDFS目录;
  2. 复制该目录到目标集群的HDFS;
  3. 在目标集群执行LOAD DATA语句加载文件到表中。

代码示例可能如下:

public class HiveDataSync {
public static void main(String[] args) {
    // 步骤1:导出源数据
    String exportCmd = "hive -e 'INSERT OVERWRITE DIRECTORY '/tmp/export' SELECT * FROM db1.tb1;'";
    executeCommand(exportCmd);

    // 步骤2:复制到目标集群HDFS(使用distcp)
    String distcpCmd = "hadoop distcp hdfs://cluster1/tmp/export hdfs://cluster2/hive/data";
    executeCommand(distcpCmd);

    // 步骤3:在目标表中加载数据
    String loadCmd = "hive -e 'LOAD DATA INPATH '/hive/data' INTO TABLE db2.tb2;'";
    executeCommand(loadCmd);
}

private static void executeCommand(String cmd) {
    try {
        Process process = Runtime.getRuntime().exec(cmd);
        // 读取输出和错误流
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new RuntimeException("Command failed: " + cmd);
        }
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
        Thread.currentThread().interrupt(); // 恢复中断
    }
}
}

不过这可能存在路径和集群地址的硬编码问题。用户需要修改这些参数。

另外,需要确保两个集群之间的HDFS可以互相访问,并且distcp命令能跨集群执行。

此外,在步骤3中,LOAD DATA语句可能需要指定正确的HDFS路径。

另一个需要注意的地方是,导出到目录后生成的数据文件(如文本或sequence file)是否与目标表的存储格式兼容。例如,如果目标表使用ORC,而源导出的是TextFile,可能会有问题?

因此,在导出时应该保持数据格式一致,或者在导入时转换。

可能需要进一步调整导出命令:

比如指定输出为文本文件: INSERT OVERWRITE LOCAL DIRECTORY ‘/tmp/export’ ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’;

然后目标表也应使用相同的分隔符和存储格式?

或者让Hive自动处理格式,如果目标表已经存在且结构正确的话。

此外,在同步前可能需要先清空目标表?或者追加插入?

用户的需求是“同步数据”,可能是覆盖,所以INSERT OVERWRITE可能更好。因此导出命令应该是:

“INSERT OVERWRITE DIRECTORY…”

同时目标表的LOAD DATA应替换现有文件?

或者使用APPEND的方式?

如果目标表要完全替换,则步骤3可能需要先TRUNCATE TABLE db2.tb2;

这也可以在Hive语句中添加。

所以代码示例中的LOAD部分可以改为:

“hive -e ‘TRUNCATE TABLE db2.tb2; LOAD DATA INPATH ‘/path’ INTO TABLE db2.tb2;’”

这样确保数据覆盖。

另外,错误处理需要更完善。比如每个步骤执行是否成功?

例如,在导出后检查文件是否存在?或者等待命令的返回码。

不过代码示例已经包含基本的异常处理。

现在总结一下:

用户的问题是亿级数据同步,所以用JDBC逐条插入可能不够高效,而批量导出导入更合适。因此给出使用Hive命令和DistCp的Java实现方案,并解释步骤和注意事项。

以下是针对从一个Hive集群同步数据到另一个Hive表的Java代码示例。考虑到数据量在亿级别,采用**批处理方式(Export/Import)**而非逐行插入会更高效。

输出结果

在这里插入图片描述

输出结果的速度在2.51 token/s ,输出了 3724个token,第一个Token在8.41s开始输出。

方案概述

  1. 导出源表数据至HDFS临时目录:使用Hive命令将cluster1db1.tb1数据导出为文本文件。
  2. 跨集群复制HDFS数据:通过hadoop distcp将导出的数据从源集群的HDFS拷贝到目标集群的HDFS。
  3. 加载数据至目标表:在cluster2的Hive表db2.tb2中使用LOAD DATA命令导入文件。

Java代码实现

import java.io.*;

public class HiveDataSync {

    public static void main(String[] args) {
        // 配置参数(需根据实际环境修改)
        String sourceCluster = "cluster1:port";  // 源集群Hive地址
        String targetCluster = "cluster2:port";  // 目标集群Hive地址
        String sourceTablePath = "/tmp/export_tb1";
        String targetHdfsPath = "/user/hive/warehouse/db2.db/tb2/data";

        try {
            // 步骤1:导出源表数据到临时目录(HDFS)
            System.out.println("步骤1: 导出源表数据...");
            String exportCmd = "hive -e 'INSERT OVERWRITE DIRECTORY '" + sourceTablePath 
                + "' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\\t' SELECT * FROM db1.tb1;'";
            executeCommand(exportCmd);

            // 步骤2:跨集群复制HDFS数据
            System.out.println("步骤2: 复制数据到目标集群...");
            String distcpCmd = "hadoop distcp hdfs://" + sourceCluster + "/" + sourceTablePath 
                + " hdfs://" + targetCluster + "/" + targetHdfsPath;
            executeCommand(distcpCmd);

            // 步骤3:加载数据到目标表
            System.out.println("步骤3: 加载数据到目标表...");
            String loadCmd = "hive -e 'LOAD DATA INPATH '" + targetHdfsPath 
                + "' INTO TABLE db2.tb2;'";
            executeCommand(loadCmd);

            System.out.println("同步完成!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 执行命令并处理输出
     */
    private static void executeCommand(String cmd) throws IOException, InterruptedException {
        Process process = Runtime.getRuntime().exec(cmd);
        
        // 读取标准输出和错误流(防止阻塞)
        new Thread(() -> {
            try (BufferedReader reader = 
                    new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println("STDOUT: " + line);
                }
            } catch (IOException e) { e.printStackTrace(); }
        }).start();

        new Thread(() -> {
            try (BufferedReader errorReader = 
                    new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
                String errLine;
                while ((errLine = errorReader.readLine()) != null) {
                    System.err.println("STDERR: " + errLine);
                }
            } catch (IOException e) { e.printStackTrace(); }
        }).start();

        // 等待命令执行完成
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new RuntimeException("命令失败:" + cmd);
        }
    }
}

关键步骤说明

  1. 导出数据

    • 使用INSERT OVERWRITE DIRECTORY将源表数据写入HDFS临时目录。
    • 指定分隔符(如\t),确保目标表能正确解析文件格式。
  2. 跨集群复制

    • hadoop distcp是Hadoop自带的分布式拷贝工具,适合处理大规模数据。
    • 需确保两集群网络互通且有权限访问彼此的HDFS路径。
  3. 加载数据到目标表

    • 使用LOAD DATA INPATH命令将HDFS文件直接加载到目标Hive表中(无需逐行插入)

    注意事项

    • 表结构一致性:确保源表和目标表的字段顺序、类型一致。

    • 分区处理:如果涉及分区数据,需在导出时指定分区条件,并调整LOAD DATA路径。

    • 性能优化

      • 使用压缩格式(如gzip)减少传输体积。
      • 调整distcp参数(如-bandwidth控制带宽)。
    • 错误处理:捕获异常并实现重试机制。

    扩展建议

    如果需要更细粒度的同步(如增量同步),可结合:

    1. 在源表添加时间戳字段,通过WHERE条件过滤新数据。
    2. 使用Hadoop的MapReduce或Spark实现分布式批处理。

    希望这段代码能为您的大数据同步任务提供参考!

运行效果

在这里插入图片描述
在这里插入图片描述

这个Q4_K_S量化的QWQ32B实测Token生成速度每秒约2.5个:

在这里插入图片描述

战99的温度在62℃附近,当对生成速度不敏感/有严厉的保密非审核属性时,可以尝试使用

注意事项

千万不要使用AMD software修改:

在这里插入图片描述

如果修改了就会导致专用GPU显存发生变化,如果不是1-2GB,就无法正常运行大模型,别问我怎么知道的!!!重要的事情说三遍!!!要恢复Bios配置!!!

尾言

至此,私有化部署了一个QWQ 32B模型。后续就可以解锁更多玩法了!!!当然也就没有把Z840+到1TB内存,借助KTransform私有化部署DeepSeek 671b的必要了。

转载请注明出处:https://lizhiyong.blog.csdn.net/article/details/147237895

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值