Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
fastllm
Commits
aefd9f11
Commit
aefd9f11
authored
Sep 06, 2023
by
zhouxiang
Browse files
dcu平台fastllm推理框架
parents
Pipeline
#543
failed with stages
in 0 seconds
Changes
186
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1023 additions
and
0 deletions
+1023
-0
example/Android/LLMAssistant/app/libs/arm64-v8a/libassistant.so
...e/Android/LLMAssistant/app/libs/arm64-v8a/libassistant.so
+0
-0
example/Android/LLMAssistant/app/libs/armeabi-v7a/libassistant.so
...Android/LLMAssistant/app/libs/armeabi-v7a/libassistant.so
+0
-0
example/Android/LLMAssistant/app/proguard-rules.pro
example/Android/LLMAssistant/app/proguard-rules.pro
+22
-0
example/Android/LLMAssistant/app/release/app-arm64-v8a-release-unsigned.apk
...MAssistant/app/release/app-arm64-v8a-release-unsigned.apk
+0
-0
example/Android/LLMAssistant/app/release/app-armeabi-v7a-release-unsigned.apk
...ssistant/app/release/app-armeabi-v7a-release-unsigned.apk
+0
-0
example/Android/LLMAssistant/app/release/app-universal-release-unsigned.apk
...MAssistant/app/release/app-universal-release-unsigned.apk
+0
-0
example/Android/LLMAssistant/app/release/app-x86-release-unsigned.apk
...oid/LLMAssistant/app/release/app-x86-release-unsigned.apk
+0
-0
example/Android/LLMAssistant/app/src/androidTest/java/com/doujiao/xiaozhihuiassistant/ExampleInstrumentedTest.java
.../doujiao/xiaozhihuiassistant/ExampleInstrumentedTest.java
+26
-0
example/Android/LLMAssistant/app/src/main/AndroidManifest.xml
...ple/Android/LLMAssistant/app/src/main/AndroidManifest.xml
+30
-0
example/Android/LLMAssistant/app/src/main/cpp/CMakeLists.txt
example/Android/LLMAssistant/app/src/main/cpp/CMakeLists.txt
+81
-0
example/Android/LLMAssistant/app/src/main/cpp/LLMChat.cpp
example/Android/LLMAssistant/app/src/main/cpp/LLMChat.cpp
+57
-0
example/Android/LLMAssistant/app/src/main/cpp/LLMChat.h
example/Android/LLMAssistant/app/src/main/cpp/LLMChat.h
+23
-0
example/Android/LLMAssistant/app/src/main/cpp/main.cpp
example/Android/LLMAssistant/app/src/main/cpp/main.cpp
+168
-0
example/Android/LLMAssistant/app/src/main/cpp/native-lib.cpp
example/Android/LLMAssistant/app/src/main/cpp/native-lib.cpp
+98
-0
example/Android/LLMAssistant/app/src/main/java/com/doujiao/core/AssistantCore.java
...ant/app/src/main/java/com/doujiao/core/AssistantCore.java
+44
-0
example/Android/LLMAssistant/app/src/main/java/com/doujiao/xiaozhihuiassistant/ChatMessage.java
...ain/java/com/doujiao/xiaozhihuiassistant/ChatMessage.java
+39
-0
example/Android/LLMAssistant/app/src/main/java/com/doujiao/xiaozhihuiassistant/MainActivity.java
...in/java/com/doujiao/xiaozhihuiassistant/MainActivity.java
+283
-0
example/Android/LLMAssistant/app/src/main/java/com/doujiao/xiaozhihuiassistant/adapter/BaseViewHolder.java
...m/doujiao/xiaozhihuiassistant/adapter/BaseViewHolder.java
+21
-0
example/Android/LLMAssistant/app/src/main/java/com/doujiao/xiaozhihuiassistant/adapter/MyAdapter.java
...va/com/doujiao/xiaozhihuiassistant/adapter/MyAdapter.java
+102
-0
example/Android/LLMAssistant/app/src/main/java/com/doujiao/xiaozhihuiassistant/utils/PrefUtil.java
.../java/com/doujiao/xiaozhihuiassistant/utils/PrefUtil.java
+29
-0
No files found.
example/Android/LLMAssistant/app/libs/arm64-v8a/libassistant.so
0 → 100644
View file @
aefd9f11
File added
example/Android/LLMAssistant/app/libs/armeabi-v7a/libassistant.so
0 → 100644
View file @
aefd9f11
File added
example/Android/LLMAssistant/app/proguard-rules.pro
0 → 100644
View file @
aefd9f11
# Add project specific ProGuard rules here.
#
You
can
control
the
set
of
applied
configuration
files
using
the
#
proguardFiles
setting
in
build
.
gradle
.
#
#
For
more
details
,
see
#
http
://
developer
.
android
.
com
/
guide
/
developing
/
tools
/
proguard
.
html
#
If
your
project
uses
WebView
with
JS
,
uncomment
the
following
#
and
specify
the
fully
qualified
class
name
to
the
JavaScript
interface
#
class
:
#-
keepclassmembers
class
fqcn
.
of
.
javascript
.
interface
.
for
.
webview
{
#
public
*
;
#
}
#
Uncomment
this
to
preserve
the
line
number
information
for
#
debugging
stack
traces
.
#-
keepattributes
SourceFile
,
LineNumberTable
#
If
you
keep
the
line
number
information
,
uncomment
this
to
#
hide
the
original
source
file
name
.
#-
renamesourcefileattribute
SourceFile
\ No newline at end of file
example/Android/LLMAssistant/app/release/app-arm64-v8a-release-unsigned.apk
0 → 100644
View file @
aefd9f11
File added
example/Android/LLMAssistant/app/release/app-armeabi-v7a-release-unsigned.apk
0 → 100644
View file @
aefd9f11
File added
example/Android/LLMAssistant/app/release/app-universal-release-unsigned.apk
0 → 100644
View file @
aefd9f11
File added
example/Android/LLMAssistant/app/release/app-x86-release-unsigned.apk
0 → 100644
View file @
aefd9f11
File added
example/Android/LLMAssistant/app/src/androidTest/java/com/doujiao/xiaozhihuiassistant/ExampleInstrumentedTest.java
0 → 100644
View file @
aefd9f11
package
com.doujiao.xiaozhihuiassistant
;
import
android.content.Context
;
import
android.support.test.InstrumentationRegistry
;
import
android.support.test.runner.AndroidJUnit4
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
static
org
.
junit
.
Assert
.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith
(
AndroidJUnit4
.
class
)
public
class
ExampleInstrumentedTest
{
@Test
public
void
useAppContext
()
{
// Context of the app under test.
Context
appContext
=
InstrumentationRegistry
.
getInstrumentation
().
getTargetContext
();
assertEquals
(
"com.doujiao.xiaozhihuiassistant"
,
appContext
.
getPackageName
());
}
}
\ No newline at end of file
example/Android/LLMAssistant/app/src/main/AndroidManifest.xml
0 → 100644
View file @
aefd9f11
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
package=
"com.doujiao.xiaozhihuiassistant"
>
<uses-permission
android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.READ_EXTERNAL_STORAGE"
/>
<application
android:allowBackup=
"true"
android:icon=
"@mipmap/ic_launcher"
android:label=
"@string/app_name"
android:roundIcon=
"@mipmap/ic_launcher_round"
android:supportsRtl=
"true"
android:largeHeap=
"true"
android:theme=
"@style/Theme.XiaoZhihuiAssistant"
>
<activity
android:name=
".MainActivity"
android:theme=
"@style/Theme.AppCompat.DayNight.NoActionBar"
android:windowSoftInputMode=
"adjustResize"
android:exported=
"true"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
example/Android/LLMAssistant/app/src/main/cpp/CMakeLists.txt
0 → 100644
View file @
aefd9f11
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required
(
VERSION 3.10.2
)
# Declares and names the project.
project
(
"assistant"
)
set
(
CMAKE_BUILD_TYPE
"Release"
)
option
(
USE_CUDA
"use cuda"
OFF
)
option
(
PY_API
"python api"
OFF
)
#可以注释掉下面优化选项
#add_definitions(${CMAKE_CXX_FLAGS} "${CMAKE_CXX_FLAGS} -march=armv8.2a+dotprod")
#
#file(GLOB_RECURSE NANODET_SOURCE ../../../../../../../src/*.cpp
# ../../../../../../../src/devices/cpu/*.cpp
# ../../../../../../../src/models/*.cpp)
#
#set(PROJECT_SOURCE
# ${NANODET_SOURCE}
# )
set
(
PROJECT_SOURCE
../../../../../../../src/fastllm.cpp
../../../../../../../src/device.cpp
../../../../../../../src/model.cpp
../../../../../../../src/executor.cpp
../../../../../../../src/devices/cpu/cpudevice.cpp
../../../../../../../src/devices/cpu/cpudevicebatch.cpp
../../../../../../../src/models/chatglm.cpp
../../../../../../../src/models/moss.cpp
../../../../../../../src/models/llama.cpp
../../../../../../../src/models/basellm.cpp
../../../../../../../src/models/qwen.cpp
)
include_directories
(
./
../../../../../../../include
../../../../../../../include/models
../../../../../../../include/utils
../../../../../../../include/devices/cpu
)
add_library
(
# Sets the name of the library.
assistant
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
${
PROJECT_SOURCE
}
LLMChat.cpp native-lib.cpp
)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library
(
# Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log
)
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries
(
# Specifies the target library.
assistant
# Links the target library to the log library
# included in the NDK.
${
log-lib
}
)
#add_executable(main main.cpp ../../../../../../../src/fastllm.cpp
# ../../../../../../../src/chatglm.cpp
# ../../../../../../../src/moss.cpp)
\ No newline at end of file
example/Android/LLMAssistant/app/src/main/cpp/LLMChat.cpp
0 → 100644
View file @
aefd9f11
#include <cstdio>
#include <cstring>
#include <iostream>
#include <getopt.h>
#include "LLMChat.h"
#include "model.h"
//void(^ __nonnull RuntimeChat)(int index,const char* _Nonnull content) = NULL;//实时回调
static
int
modeltype
=
0
;
static
char
*
modelpath
=
NULL
;
static
std
::
unique_ptr
<
fastllm
::
basellm
>
chatGlm
=
NULL
;
static
int
sRound
=
0
;
static
std
::
string
history
;
static
RuntimeResultMobile
g_callback
=
NULL
;
std
::
string
initGptConf
(
const
char
*
modelPath
,
int
threads
)
{
fastllm
::
SetThreads
(
threads
);
LOG_Debug
(
"@@init llmpath:%s
\n
"
,
modelPath
);
chatGlm
=
fastllm
::
CreateLLMModelFromFile
(
modelPath
);
if
(
chatGlm
!=
NULL
)
{
std
::
string
modelName
=
chatGlm
->
model_type
;
LOG_Debug
(
"@@model name:%s
\n
"
,
modelName
.
c_str
());
return
modelName
;
}
LOG_Debug
(
"@@CreateLLMModelFromFile failed."
);
return
""
;
}
int
chat
(
const
char
*
prompt
,
RuntimeResultMobile
chatCallback
)
{
std
::
string
ret
=
""
;
g_callback
=
chatCallback
;
LOG_Debug
(
"@@init llm:type:%d,prompt:%s
\n
"
,
modeltype
,
prompt
);
std
::
string
input
(
prompt
);
if
(
input
==
"reset"
)
{
history
=
""
;
sRound
=
0
;
g_callback
(
0
,
"Done!"
);
g_callback
(
-
1
,
""
);
return
0
;
}
ret
=
chatGlm
->
Response
(
chatGlm
->
MakeInput
(
history
,
sRound
,
input
),
[](
int
index
,
const
char
*
content
)
{
g_callback
(
index
,
content
);
});
history
=
chatGlm
->
MakeHistory
(
history
,
sRound
,
input
,
ret
);
sRound
++
;
long
len
=
ret
.
length
();
return
len
;
}
void
uninitLLM
()
{
}
example/Android/LLMAssistant/app/src/main/cpp/LLMChat.h
0 → 100644
View file @
aefd9f11
//
// LLMChat.h
// LLMChat
//
// Created by 胡其斌 on 2023/5/18.
//
#ifdef __cplusplus
extern
"C"
{
#endif
#include <android/log.h>
#define LOG_Debug(...) __android_log_print(ANDROID_LOG_DEBUG, "Assistant", __VA_ARGS__)
typedef
void
(
*
RuntimeResultMobile
)(
int
index
,
const
char
*
content
);
std
::
string
initGptConf
(
const
char
*
modelPath
,
int
threads
);
int
chat
(
const
char
*
prompt
,
RuntimeResultMobile
chatCallback
);
void
uninitLLM
();
#ifdef __cplusplus
}
#endif
example/Android/LLMAssistant/app/src/main/cpp/main.cpp
0 → 100644
View file @
aefd9f11
#include <cstdio>
#include <cstring>
#include <iostream>
#include <getopt.h>
#include "factoryllm.h"
static
factoryllm
fllm
;
static
int
modeltype
=
0
;
static
char
*
modelpath
=
NULL
;
static
fastllm
::
basellm
*
chatGlm
=
fllm
.
createllm
(
LLM_TYPE_CHATGLM
);
static
fastllm
::
basellm
*
moss
=
fllm
.
createllm
(
LLM_TYPE_MOSS
);
static
int
sRound
=
0
;
static
std
::
string
history
;
struct
RunConfig
{
int
model
=
LLM_TYPE_CHATGLM
;
// 模型类型, LLM_TYPE_CHATGLM:chatglm, LLM_TYPE_MOSS:moss
std
::
string
path
=
"/sdcard/chatglm-6b-int4.bin"
;
// 模型文件路径
int
threads
=
6
;
// 使用的线程数
};
static
struct
option
long_options
[]
=
{
{
"help"
,
no_argument
,
nullptr
,
'h'
},
{
"model"
,
required_argument
,
nullptr
,
'm'
},
{
"path"
,
required_argument
,
nullptr
,
'p'
},
{
"threads"
,
required_argument
,
nullptr
,
't'
},
{
nullptr
,
0
,
nullptr
,
0
},
};
void
Usage
()
{
std
::
cout
<<
"Usage:"
<<
std
::
endl
;
std
::
cout
<<
"[-h|--help]: 显示帮助"
<<
std
::
endl
;
std
::
cout
<<
"<-m|--model> <args>: 模型类型,默认为chatglm, 可以设置为0, moss:1"
<<
std
::
endl
;
std
::
cout
<<
"<-p|--path> <args>: 模型文件的路径"
<<
std
::
endl
;
std
::
cout
<<
"<-t|--threads> <args>: 使用的线程数量"
<<
std
::
endl
;
}
void
ParseArgs
(
int
argc
,
char
**
argv
,
RunConfig
&
config
)
{
int
opt
;
int
option_index
=
0
;
const
char
*
opt_string
=
"h:m:p:t:"
;
while
((
opt
=
getopt_long_only
(
argc
,
argv
,
opt_string
,
long_options
,
&
option_index
))
!=
-
1
)
{
switch
(
opt
)
{
case
'h'
:
Usage
();
exit
(
0
);
case
'm'
:
config
.
model
=
atoi
(
argv
[
optind
-
1
]);
break
;
case
'p'
:
config
.
path
=
argv
[
optind
-
1
];
break
;
case
't'
:
config
.
threads
=
atoi
(
argv
[
optind
-
1
]);
break
;
default:
Usage
();
exit
(
-
1
);
}
}
}
int
initLLMConf
(
int
model
,
const
char
*
modelPath
,
int
threads
)
{
fastllm
::
SetThreads
(
threads
);
modeltype
=
model
;
// printf("@@init llm:type:%d,path:%s\n",model,modelPath);
if
(
modeltype
==
0
)
{
chatGlm
->
LoadFromFile
(
modelPath
);
}
if
(
modeltype
==
1
)
{
moss
->
LoadFromFile
(
modelPath
);
}
return
0
;
}
int
chat
(
const
char
*
prompt
)
{
std
::
string
ret
=
""
;
//printf("@@init llm:type:%d,prompt:%s\n",modeltype,prompt);
std
::
string
input
(
prompt
);
if
(
modeltype
==
0
)
{
if
(
input
==
"reset"
)
{
history
=
""
;
sRound
=
0
;
return
0
;
}
history
+=
(
"[Round "
+
std
::
to_string
(
sRound
++
)
+
"]
\n
问:"
+
input
);
auto
prompt
=
sRound
>
1
?
history
:
input
;
ret
=
chatGlm
->
Response
(
prompt
,[](
int
index
,
const
char
*
content
){
if
(
index
==
0
)
{
printf
(
"ChatGLM:"
);
}
printf
(
"%s"
,
content
);
if
(
index
==
-
1
)
{
printf
(
"
\n
"
);
}
});
history
+=
(
"
\n
答:"
+
ret
+
"
\n
"
);
}
if
(
modeltype
==
1
)
{
auto
prompt
=
"You are an AI assistant whose name is MOSS. <|Human|>: "
+
input
+
"<eoh>"
;
ret
=
moss
->
Response
(
prompt
,[](
int
index
,
const
char
*
content
){
if
(
index
==
0
)
{
printf
(
"MOSS:"
);
}
printf
(
"%s"
,
content
);
if
(
index
==
-
1
)
{
printf
(
"
\n
"
);
}
});
}
long
len
=
ret
.
length
();
return
len
;
}
void
uninitLLM
()
{
if
(
chatGlm
)
{
delete
chatGlm
;
chatGlm
=
NULL
;
}
if
(
moss
)
{
delete
moss
;
moss
=
NULL
;
}
}
int
main
(
int
argc
,
char
**
argv
)
{
RunConfig
config
;
ParseArgs
(
argc
,
argv
,
config
);
initLLMConf
(
config
.
model
,
config
.
path
.
c_str
(),
config
.
threads
);
if
(
config
.
model
==
LLM_TYPE_MOSS
)
{
while
(
true
)
{
printf
(
"用户: "
);
std
::
string
input
;
std
::
getline
(
std
::
cin
,
input
);
if
(
input
==
"stop"
)
{
break
;
}
chat
(
input
.
c_str
());
}
}
else
if
(
config
.
model
==
LLM_TYPE_CHATGLM
)
{
while
(
true
)
{
printf
(
"用户: "
);
std
::
string
input
;
std
::
getline
(
std
::
cin
,
input
);
if
(
input
==
"stop"
)
{
break
;
}
chat
(
input
.
c_str
());
}
}
else
{
Usage
();
exit
(
-
1
);
}
return
0
;
}
example/Android/LLMAssistant/app/src/main/cpp/native-lib.cpp
0 → 100644
View file @
aefd9f11
#include <jni.h>
#include <string>
#include "LLMChat.h"
JavaVM
*
g_javaVM
=
NULL
;
jobject
g_obj
;
void
initGvm
(
JNIEnv
*
env
,
jobject
thiz
)
{
if
(
g_javaVM
==
NULL
)
{
env
->
GetJavaVM
(
&
g_javaVM
);
g_obj
=
env
->
NewGlobalRef
(
thiz
);
}
}
void
chatCb
(
int
index
,
const
char
*
content
)
{
JNIEnv
*
env
=
NULL
;
int
mNeedDetach
=
0
;
//获取当前native线程是否有没有被附加到jvm环境中
int
getEnvStat
=
g_javaVM
->
GetEnv
((
void
**
)
&
env
,
JNI_VERSION_1_6
);
if
(
getEnvStat
==
JNI_EDETACHED
)
{
//如果没有, 主动附加到jvm环境中,获取到env
if
(
g_javaVM
->
AttachCurrentThread
(
&
env
,
NULL
)
!=
0
)
{
LOG_Debug
(
"Unable to AttachCurrentThread"
);
return
;
}
mNeedDetach
=
1
;
}
//通过全局变量g_obj 获取到要回调的类
jclass
javaClass
=
env
->
GetObjectClass
(
g_obj
);
//env->FindClass("com/doujiao/core/AssistantCore");//
if
(
javaClass
==
0
)
{
LOG_Debug
(
"Unable to find class"
);
if
(
mNeedDetach
)
{
g_javaVM
->
DetachCurrentThread
();
}
return
;
}
jmethodID
jgetDBpathMethod
=
env
->
GetMethodID
(
javaClass
,
"reportChat"
,
"(Ljava/lang/String;I)V"
);
if
(
jgetDBpathMethod
==
NULL
)
{
LOG_Debug
(
"Unable to find method:jgetDBpathMethod"
);
return
;
}
jobject
bb
=
env
->
NewDirectByteBuffer
((
void
*
)
content
,
strlen
(
content
));
jclass
cls_Charset
=
env
->
FindClass
(
"java/nio/charset/Charset"
);
jmethodID
mid_Charset_forName
=
env
->
GetStaticMethodID
(
cls_Charset
,
"forName"
,
"(Ljava/lang/String;)Ljava/nio/charset/Charset;"
);
jobject
charset
=
env
->
CallStaticObjectMethod
(
cls_Charset
,
mid_Charset_forName
,
env
->
NewStringUTF
(
"UTF-8"
));
jmethodID
mid_Charset_decode
=
env
->
GetMethodID
(
cls_Charset
,
"decode"
,
"(Ljava/nio/ByteBuffer;)Ljava/nio/CharBuffer;"
);
jobject
cb
=
env
->
CallObjectMethod
(
charset
,
mid_Charset_decode
,
bb
);
env
->
DeleteLocalRef
(
bb
);
jclass
cls_CharBuffer
=
env
->
FindClass
(
"java/nio/CharBuffer"
);
jmethodID
mid_CharBuffer_toString
=
env
->
GetMethodID
(
cls_CharBuffer
,
"toString"
,
"()Ljava/lang/String;"
);
jstring
str
=
static_cast
<
jstring
>
(
env
->
CallObjectMethod
(
cb
,
mid_CharBuffer_toString
));
env
->
CallVoidMethod
(
g_obj
,
jgetDBpathMethod
,
str
,
index
);
env
->
DeleteLocalRef
(
javaClass
);
//释放当前线程
if
(
mNeedDetach
)
{
g_javaVM
->
DetachCurrentThread
();
}
env
=
NULL
;
}
extern
"C"
JNIEXPORT
jstring
JNICALL
Java_com_doujiao_core_AssistantCore_initLLMConfig
(
JNIEnv
*
env
,
jobject
obj
,
jstring
modelpath
,
jint
threads
)
{
initGvm
(
env
,
obj
);
const
char
*
path
=
env
->
GetStringUTFChars
(
modelpath
,
NULL
);
std
::
string
ret
=
initGptConf
(
path
,
threads
);
LOG_Debug
(
"@@@initLLMConfig:%s"
,
ret
.
c_str
());
env
->
ReleaseStringUTFChars
(
modelpath
,
path
);
return
env
->
NewStringUTF
(
ret
.
c_str
());
}
extern
"C"
JNIEXPORT
jint
JNICALL
Java_com_doujiao_core_AssistantCore_chat
(
JNIEnv
*
env
,
jobject
obj
,
jstring
prompt
)
{
initGvm
(
env
,
obj
);
const
char
*
question
=
env
->
GetStringUTFChars
(
prompt
,
NULL
);
chat
(
question
,[](
int
index
,
const
char
*
content
){
chatCb
(
index
,
content
);
});
// chatCb(1,"content");
return
0
;
}
extern
"C"
JNIEXPORT
void
JNICALL
Java_com_doujiao_core_AssistantCore_uninitLLM
(
JNIEnv
*
env
,
jobject
/* this */
)
{
uninitLLM
();
}
\ No newline at end of file
example/Android/LLMAssistant/app/src/main/java/com/doujiao/core/AssistantCore.java
0 → 100644
View file @
aefd9f11
package
com.doujiao.core
;
import
android.support.annotation.Keep
;
import
android.util.Log
;
public
class
AssistantCore
{
private
static
AssistantCore
instance
=
null
;
private
static
runtimeResult
mRuntimeRes
=
null
;
static
{
System
.
loadLibrary
(
"assistant"
);
}
/*静态对象*/
public
static
AssistantCore
getInstance
(){
if
(
instance
==
null
){
instance
=
new
AssistantCore
();
}
return
instance
;
}
public
String
initLLM
(
String
path
,
runtimeResult
callback
)
{
mRuntimeRes
=
callback
;
return
initLLMConfig
(
path
,
8
);
}
@Keep
public
void
reportChat
(
String
content
,
int
index
)
{
Log
.
d
(
"@@@"
,
"recv:"
+
content
+
",index:"
+
index
);
if
(
mRuntimeRes
!=
null
)
{
mRuntimeRes
.
callbackResult
(
index
,
content
);
}
}
public
interface
runtimeResult
{
void
callbackResult
(
int
index
,
String
content
);
}
private
native
String
initLLMConfig
(
String
path
,
int
threads
);
public
native
int
chat
(
String
prompt
);
public
native
int
uninitLLM
();
}
example/Android/LLMAssistant/app/src/main/java/com/doujiao/xiaozhihuiassistant/ChatMessage.java
0 → 100644
View file @
aefd9f11
package
com.doujiao.xiaozhihuiassistant
;
/**
* Created by chenpengfei on 2016/10/27.
*/
public
class
ChatMessage
{
private
String
content
;
private
int
type
;
public
ChatMessage
(
String
content
,
int
type
)
{
this
.
content
=
content
;
this
.
type
=
type
;
}
public
ChatMessage
(
String
content
)
{
this
(
content
,
1
);
}
public
String
getContent
()
{
return
content
;
}
public
void
setContent
(
String
content
)
{
this
.
content
=
content
;
}
public
int
getType
()
{
return
type
;
}
public
void
setType
(
int
type
)
{
this
.
type
=
type
;
}
}
example/Android/LLMAssistant/app/src/main/java/com/doujiao/xiaozhihuiassistant/MainActivity.java
0 → 100644
View file @
aefd9f11
package
com.doujiao.xiaozhihuiassistant
;
import
android.Manifest
;
import
android.app.Activity
;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.net.Uri
;
import
android.os.Build
;
import
android.os.Environment
;
import
android.os.Handler
;
import
android.os.Message
;
import
android.provider.Settings
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.support.v4.app.ActivityCompat
;
import
android.support.v7.app.AppCompatActivity
;
import
android.os.Bundle
;
import
android.support.v7.widget.LinearLayoutManager
;
import
android.support.v7.widget.RecyclerView
;
import
android.text.TextUtils
;
import
android.util.Log
;
import
android.view.View
;
import
android.widget.Button
;
import
android.widget.EditText
;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
com.doujiao.core.AssistantCore
;
import
com.doujiao.xiaozhihuiassistant.adapter.MyAdapter
;
import
com.doujiao.xiaozhihuiassistant.databinding.ActivityMainBinding
;
import
com.doujiao.xiaozhihuiassistant.utils.PrefUtil
;
import
com.doujiao.xiaozhihuiassistant.utils.StatusBarUtils
;
import
com.doujiao.xiaozhihuiassistant.utils.UriUtils
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.FileOutputStream
;
import
java.io.FileWriter
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
MainActivity
extends
AppCompatActivity
{
private
static
final
int
MSG_TYPE_RECVRESULT
=
0
;
private
static
final
int
MSG_TYPE_INITMODEL_END
=
1
;
private
ActivityMainBinding
binding
;
private
volatile
boolean
mIsRunning
=
false
;
private
EditText
mInputEt
=
null
;
private
TextView
mTvTips
=
null
;
private
RecyclerView
mRcyViewMess
=
null
;
private
Button
sendBtn
;
private
String
mInputContent
=
""
;
private
String
mOutPutContent
=
""
;
private
boolean
mIsInit
=
false
;
ArrayList
<
ChatMessage
>
messageList
=
new
ArrayList
<>();
private
MyAdapter
myAdapter
=
null
;
//读写权限
private
static
String
[]
PERMISSIONS_STORAGE
=
{
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
};
//请求状态码
private
final
static
int
REQUEST_PERMISSION_CODE
=
1
;
protected
static
Uri
modelUri
=
null
;
Handler
mHandler
=
new
Handler
()
{
@Override
public
void
handleMessage
(
Message
msg
)
{
super
.
handleMessage
(
msg
);
int
msgType
=
msg
.
what
;
switch
(
msgType
)
{
case
MSG_TYPE_RECVRESULT:
{
int
index
=
msg
.
arg1
;
String
content
=
(
String
)
msg
.
obj
;
if
(
index
==
0
)
{
addMsgList
(
content
,
2
);
}
if
(
index
>
0
)
{
updateMsgList
(
content
);
}
if
(
index
==
-
1
)
{
// sendBtn.setEnabled(true);
}
}
break
;
case
MSG_TYPE_INITMODEL_END:
String
model
=
(
String
)
msg
.
obj
;
if
(
TextUtils
.
isEmpty
(
model
))
{
Toast
.
makeText
(
getApplicationContext
(),
"模型不正确!请下载正确模型。"
,
Toast
.
LENGTH_SHORT
).
show
();
}
else
{
sendBtn
.
setEnabled
(
true
);
mInputEt
.
setText
(
""
);
mTvTips
.
setText
(
PrefUtil
.
getModelPath
());
Toast
.
makeText
(
getApplicationContext
(),
"欢迎使用:"
+
model
,
Toast
.
LENGTH_SHORT
).
show
();
mIsInit
=
true
;
}
break
;
}
}
};
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
binding
=
ActivityMainBinding
.
inflate
(
getLayoutInflater
());
setContentView
(
binding
.
getRoot
());
PrefUtil
.
initPref
(
getApplicationContext
());
initView
();
if
(
Build
.
VERSION
.
SDK_INT
>
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
if
(
ActivityCompat
.
checkSelfPermission
(
this
,
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
initModel
();
}
else
{
sendBtn
.
setEnabled
(
false
);
ActivityCompat
.
requestPermissions
(
this
,
PERMISSIONS_STORAGE
,
REQUEST_PERMISSION_CODE
);
}
}
StatusBarUtils
.
hideStatusBar
(
getWindow
(),
true
);
}
private
void
initModel
()
{
//init:
String
modelPath
=
PrefUtil
.
getModelPath
();
if
(!
modelPath
.
isEmpty
())
{
mTvTips
.
setText
(
"模型加载中.."
);
new
Thread
(
new
Runnable
()
{
@Override
public
void
run
()
{
if
(
modelUri
!=
null
)
{
try
{
Log
.
d
(
MainActivity
.
class
.
getName
(),
" writing model file to "
+
modelPath
);
InputStream
inputStream
=
getContentResolver
().
openInputStream
(
modelUri
);
FileOutputStream
fileOutputStream
=
new
FileOutputStream
(
modelPath
);
byte
[]
buffer
=
new
byte
[
1024
];
int
bytesRead
;
while
((
bytesRead
=
inputStream
.
read
(
buffer
))
!=
-
1
)
{
fileOutputStream
.
write
(
buffer
,
0
,
bytesRead
);
}
fileOutputStream
.
close
();
inputStream
.
close
();
Log
.
d
(
"@@@"
,
"model file write in "
+
modelPath
);
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
String
path
=
PrefUtil
.
getModelPath
();
//Environment.getExternalStorageDirectory().getAbsolutePath() + "/chatglm-6b-int4.bin";
File
file
=
new
File
(
path
);
if
(!
file
.
exists
()
||
file
.
length
()
<
1024
*
1024
*
1024
)
{
PrefUtil
.
setModelPath
(
""
);
String
modelType
=
""
;
Message
msg
=
Message
.
obtain
();
msg
.
obj
=
modelType
;
msg
.
what
=
MSG_TYPE_INITMODEL_END
;
mHandler
.
sendMessage
(
msg
);
return
;
}
String
modelType
=
AssistantCore
.
getInstance
().
initLLM
(
path
,
new
AssistantCore
.
runtimeResult
()
{
@Override
public
void
callbackResult
(
int
index
,
String
content
)
{
Message
msg
=
Message
.
obtain
();
msg
.
what
=
MSG_TYPE_RECVRESULT
;
msg
.
arg1
=
index
;
msg
.
obj
=
content
;
mHandler
.
sendMessage
(
msg
);
}
});
Log
.
d
(
"@@@"
,
"model:"
+
modelType
);
Message
msg
=
Message
.
obtain
();
msg
.
obj
=
modelType
;
msg
.
what
=
MSG_TYPE_INITMODEL_END
;
mHandler
.
sendMessage
(
msg
);
}
}).
start
();
}
else
{
mTvTips
.
setText
(
getString
(
R
.
string
.
app_model_tips
));
}
}
public
void
initView
()
{
mTvTips
=
findViewById
(
R
.
id
.
tv_tips
);
mInputEt
=
findViewById
(
R
.
id
.
edit_input
);
mRcyViewMess
=
findViewById
(
R
.
id
.
rv_msgs
);
mRcyViewMess
.
setLayoutManager
(
new
LinearLayoutManager
(
this
));
myAdapter
=
new
MyAdapter
(
this
);
mRcyViewMess
.
setAdapter
(
myAdapter
);
myAdapter
.
setMessages
(
messageList
);
sendBtn
=
findViewById
(
R
.
id
.
btn_send
);
if
(!
mIsInit
)
sendBtn
.
setEnabled
(
false
);
sendBtn
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
view
)
{
sendMsg
();
}
});
Button
btnSel
=
findViewById
(
R
.
id
.
btn_sel
);
btnSel
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
view
)
{
if
(!
mIsRunning
)
{
Intent
intent
=
new
Intent
(
Intent
.
ACTION_GET_CONTENT
);
intent
.
setType
(
"*/*"
);
startActivityForResult
(
Intent
.
createChooser
(
intent
,
"需要选择文件"
),
1
);
}
else
{
Toast
.
makeText
(
getApplicationContext
(),
"Is Running..."
,
Toast
.
LENGTH_SHORT
).
show
();
}
}
});
}
public
void
updateMsgList
(
String
content
)
{
ChatMessage
msg
=
messageList
.
get
(
messageList
.
size
()
-
1
);
messageList
.
remove
(
messageList
.
size
()
-
1
);
msg
.
setContent
(
msg
.
getContent
()
+
content
);
messageList
.
add
(
msg
);
myAdapter
.
setMessages
(
messageList
);
myAdapter
.
notifyItemChanged
(
messageList
.
size
()
-
1
);
}
public
void
addMsgList
(
String
content
,
int
role
)
{
messageList
.
add
(
new
ChatMessage
(
content
,
role
));
myAdapter
.
setMessages
(
messageList
);
myAdapter
.
notifyItemInserted
(
messageList
.
size
());
}
public
void
sendMsg
()
{
mInputContent
=
mInputEt
.
getText
().
toString
();
if
(
mInputContent
.
isEmpty
())
{
Toast
.
makeText
(
getApplicationContext
(),
"输入不能为空"
,
Toast
.
LENGTH_SHORT
).
show
();
return
;
}
if
(!
mIsRunning
)
{
mIsRunning
=
true
;
addMsgList
(
mInputContent
,
1
);
mInputEt
.
setText
(
""
);
new
Thread
(
new
Runnable
()
{
@Override
public
void
run
()
{
int
ret
=
AssistantCore
.
getInstance
().
chat
(
mInputContent
);
Log
.
d
(
"@@@"
,
"chat end:"
+
ret
);
mIsRunning
=
false
;
}
}).
start
();
}
else
{
Toast
.
makeText
(
getApplicationContext
(),
"Is Running..."
,
Toast
.
LENGTH_SHORT
).
show
();
}
}
@Override
public
void
onRequestPermissionsResult
(
int
requestCode
,
@NonNull
String
[]
permissions
,
@NonNull
int
[]
grantResults
)
{
super
.
onRequestPermissionsResult
(
requestCode
,
permissions
,
grantResults
);
if
(
requestCode
==
REQUEST_PERMISSION_CODE
)
{
boolean
isGrant
=
true
;
for
(
int
i
=
0
;
i
<
permissions
.
length
;
i
++)
{
int
grantResult
=
grantResults
[
i
];
if
(
grantResult
!=
PackageManager
.
PERMISSION_GRANTED
)
{
isGrant
=
false
;
}
}
if
(
isGrant
)
{
initModel
();
}
else
{
Toast
.
makeText
(
this
,
"请允许访问文件"
,
Toast
.
LENGTH_SHORT
).
show
();
}
}
}
@Override
protected
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
@Nullable
Intent
data
)
{
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
);
if
(
resultCode
==
Activity
.
RESULT_OK
)
{
Uri
uri
=
data
.
getData
();
String
pathString
=
UriUtils
.
getPath
(
this
,
uri
);
modelUri
=
null
;
if
(
pathString
==
null
||
pathString
.
length
()==
0
||
!
pathString
.
startsWith
(
"/"
)){
pathString
=
getApplicationContext
().
getExternalFilesDir
(
"models"
)
+
"/model2.flm"
;
modelUri
=
uri
;
}
Log
.
d
(
MainActivity
.
class
.
getName
(),
"uri: "
+
uri
+
" pathString"
);
PrefUtil
.
setModelPath
(
pathString
);
initModel
();
}
}
}
example/Android/LLMAssistant/app/src/main/java/com/doujiao/xiaozhihuiassistant/adapter/BaseViewHolder.java
0 → 100644
View file @
aefd9f11
package
com.doujiao.xiaozhihuiassistant.adapter
;
import
android.support.v7.widget.RecyclerView
;
import
android.view.View
;
/**
* Created by chenpengfei on 2016/10/27.
*/
public
class
BaseViewHolder
extends
RecyclerView
.
ViewHolder
{
private
View
iv
;
public
BaseViewHolder
(
View
itemView
)
{
super
(
itemView
);
iv
=
itemView
;
}
public
View
findViewById
(
int
id
)
{
return
iv
.
findViewById
(
id
);
}
}
example/Android/LLMAssistant/app/src/main/java/com/doujiao/xiaozhihuiassistant/adapter/MyAdapter.java
0 → 100644
View file @
aefd9f11
package
com.doujiao.xiaozhihuiassistant.adapter
;
import
android.app.Activity
;
import
android.support.v7.widget.RecyclerView
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
com.doujiao.xiaozhihuiassistant.ChatMessage
;
import
com.doujiao.xiaozhihuiassistant.R
;
import
com.doujiao.xiaozhihuiassistant.utils.StatusBarUtils
;
import
com.doujiao.xiaozhihuiassistant.widget.ChatPromptViewManager
;
import
com.doujiao.xiaozhihuiassistant.widget.Location
;
import
com.doujiao.xiaozhihuiassistant.widget.PromptViewHelper
;
import
java.util.List
;
public
class
MyAdapter
extends
RecyclerView
.
Adapter
<
BaseViewHolder
>
{
private
List
<
ChatMessage
>
mChatMessageList
=
null
;
private
Activity
mActivity
;
public
MyAdapter
(
Activity
activity
)
{
mActivity
=
activity
;
}
public
void
setMessages
(
List
<
ChatMessage
>
chatMessageList
)
{
mChatMessageList
=
chatMessageList
;
}
@Override
public
BaseViewHolder
onCreateViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
if
(
viewType
==
1
)
{
return
new
LeftViewHolder
(
View
.
inflate
(
mActivity
,
R
.
layout
.
activity_item_left
,
null
));
}
else
{
return
new
RightViewHolder
(
View
.
inflate
(
mActivity
,
R
.
layout
.
activity_item_right
,
null
));
}
}
@Override
public
int
getItemCount
()
{
return
mChatMessageList
.
size
();
}
@Override
public
int
getItemViewType
(
int
position
)
{
return
mChatMessageList
.
get
(
position
).
getType
();
}
@Override
public
void
onBindViewHolder
(
BaseViewHolder
holder
,
int
position
)
{
PromptViewHelper
pvHelper
=
new
PromptViewHelper
(
mActivity
);
ChatMessage
chatMessage
=
mChatMessageList
.
get
(
position
);
if
(
holder
instanceof
LeftViewHolder
)
{
LeftViewHolder
leftViewHolder
=
(
LeftViewHolder
)
holder
;
leftViewHolder
.
tv
.
setText
(
chatMessage
.
getContent
());
pvHelper
.
setPromptViewManager
(
new
ChatPromptViewManager
(
mActivity
));
}
if
(
holder
instanceof
RightViewHolder
)
{
RightViewHolder
rightViewHolder
=
(
RightViewHolder
)
holder
;
rightViewHolder
.
tv
.
setText
(
chatMessage
.
getContent
());
pvHelper
.
setPromptViewManager
(
new
ChatPromptViewManager
(
mActivity
,
Location
.
TOP_RIGHT
));
}
pvHelper
.
addPrompt
(
holder
.
itemView
.
findViewById
(
R
.
id
.
textview_content
));
pvHelper
.
setOnItemClickListener
(
new
PromptViewHelper
.
OnItemClickListener
()
{
@Override
public
void
onItemClick
(
int
position
)
{
String
str
=
""
;
switch
(
position
)
{
case
0
:
str
=
"已复制到剪贴板!"
;
TextView
tv
=
holder
.
itemView
.
findViewById
(
R
.
id
.
textview_content
);
StatusBarUtils
.
copyStr2ClibBoard
(
mActivity
.
getApplicationContext
(),
tv
.
getText
().
toString
());
break
;
}
Toast
.
makeText
(
mActivity
,
str
,
Toast
.
LENGTH_SHORT
).
show
();
}
});
}
class
LeftViewHolder
extends
BaseViewHolder
{
TextView
tv
;
public
LeftViewHolder
(
View
view
)
{
super
(
view
);
tv
=
(
TextView
)
findViewById
(
R
.
id
.
textview_content
);
}
}
class
RightViewHolder
extends
BaseViewHolder
{
TextView
tv
;
public
RightViewHolder
(
View
view
)
{
super
(
view
);
tv
=
(
TextView
)
findViewById
(
R
.
id
.
textview_content
);
}
}
}
example/Android/LLMAssistant/app/src/main/java/com/doujiao/xiaozhihuiassistant/utils/PrefUtil.java
0 → 100644
View file @
aefd9f11
package
com.doujiao.xiaozhihuiassistant.utils
;
import
android.content.Context
;
import
android.content.SharedPreferences
;
public
class
PrefUtil
{
private
static
final
String
SF_NAME
=
"com.doujiao.llm.config"
;
private
static
final
String
MOLE_PATH
=
"llm_path"
;
private
static
SharedPreferences
mPref
;
public
static
void
initPref
(
Context
context
)
{
if
(
mPref
==
null
)
{
mPref
=
context
.
getSharedPreferences
(
SF_NAME
,
Context
.
MODE_PRIVATE
);
}
}
public
static
void
setModelPath
(
String
path
)
{
if
(
mPref
!=
null
)
{
mPref
.
edit
().
putString
(
MOLE_PATH
,
path
).
apply
();
}
}
public
static
String
getModelPath
()
{
if
(
mPref
!=
null
)
{
return
mPref
.
getString
(
MOLE_PATH
,
""
);
}
return
""
;
}
}
Prev
1
2
3
4
5
6
…
10
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment