使用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
硬件 | 关键参数 |
---|---|
CPU | 7840hs 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
笔者使用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代码先从源集群读取数据,然后批量插入到目标集群的表中?
比如步骤:
- 连接cluster1的Hive JDBC,执行SELECT * FROM db1.tb1;
- 获取结果集,逐行读取并保存为某种格式(比如对象);
- 将这些数据分批插入到cluster2的db2.tb2。
但问题在于亿级数据这样处理可能效率太低。JDBC逐条处理在大数据量时可能会很慢,甚至内存溢出?
有没有更好的方法?或者使用Hive的LOAD DATA命令加载文件数据?
或许可以采用中间存储的方式:比如把源表的数据导出为文本文件,然后上传到目标集群的HDFS,再用Hive的LOAD命令导入。这样可能更快。
那Java代码可以分为几个步骤:
- 连接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代码,所以或许分两部分:
第一种方法:
- 使用JDBC读取源表的数据行,
- 将每批数据插入到目标表。
但是这样可能会遇到连接池的问题,以及网络延迟导致速度慢。对于亿级数据可能需要优化,比如批量执行insert语句。
例如,每次处理几百条记录作为一个批次,然后批量插入到目标表?
Hive的JDBC支持批量操作吗?比如用PreparedStatement.addBatch() ?
另一种方法是:
在源集群导出数据到文件(如CSV或文本),然后上传到目标集群的HDFS路径,再通过LOAD DATA命令加载到目标表。
这样可能更高效。代码可以分为三个步骤:
- 连接源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实现,所以可能需要编写一个完整的流程代码,包括:
- 在source集群的Hive中导出数据到某个位置(比如HDFS路径);
- 将该数据从source集群的HDFS复制到target集群的HDFS;
- 在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命令加载。
所以可能需要这样的步骤:
代码流程:
- 在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);
不过跨平台问题需要注意。
- 将导出的数据目录从cluster1复制到cluster2的HDFS: 例如使用DistCp: String distcpCmd = “hadoop distcp hdfs://sourceCluster/tmp/export hdfs://targetCluster/path”; 执行该命令。
- 在目标集群上运行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:
大致步骤:
- 导出源表到HDFS目录;
- 复制该目录到目标集群的HDFS;
- 在目标集群执行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开始输出。
方案概述
- 导出源表数据至HDFS临时目录:使用Hive命令将
cluster1
的db1.tb1
数据导出为文本文件。 - 跨集群复制HDFS数据:通过
hadoop distcp
将导出的数据从源集群的HDFS拷贝到目标集群的HDFS。 - 加载数据至目标表:在
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);
}
}
}
关键步骤说明
-
导出数据:
- 使用
INSERT OVERWRITE DIRECTORY
将源表数据写入HDFS临时目录。 - 指定分隔符(如
\t
),确保目标表能正确解析文件格式。
- 使用
-
跨集群复制:
hadoop distcp
是Hadoop自带的分布式拷贝工具,适合处理大规模数据。- 需确保两集群网络互通且有权限访问彼此的HDFS路径。
-
加载数据到目标表:
- 使用
LOAD DATA INPATH
命令将HDFS文件直接加载到目标Hive表中(无需逐行插入)
注意事项
-
表结构一致性:确保源表和目标表的字段顺序、类型一致。
-
分区处理:如果涉及分区数据,需在导出时指定分区条件,并调整
LOAD DATA
路径。 -
性能优化
:
- 使用压缩格式(如gzip)减少传输体积。
- 调整
distcp
参数(如-bandwidth
控制带宽)。
-
错误处理:捕获异常并实现重试机制。
扩展建议
如果需要更细粒度的同步(如增量同步),可结合:
- 在源表添加时间戳字段,通过WHERE条件过滤新数据。
- 使用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