Skip to content

Commit cf99b56

Browse files
kirklandsignmeta-codesync[bot]
authored andcommitted
Convert Android LLM extension from Java to Kotlin (#19211)
Summary: Pull Request resolved: #19211 Convert LlmModule, LlmCallback, LlmGenerationConfig, and LlmModuleConfig from Java to Kotlin while preserving all public API signatures and JNI compatibility. Key changes: - Use Kotlin idioms: `external fun` for native methods, `companion object` for static members, `require()` for validation, `apply {}` in Builders - Preserve HybridData/fbjni pattern with DoNotStrip and JvmStatic - Add JvmName annotations for boolean getters (isEcho, isWarming) to maintain Java source compatibility - Keep all constructor overloads as secondary constructors for backward compatibility with Java callers (e.g., benchmark LlmModelRunner) - Update BUCK target language from JAVA to KOTLIN - Remove package-info.java (no Kotlin equivalent needed) Differential Revision: D102880053
1 parent d767516 commit cf99b56

8 files changed

Lines changed: 963 additions & 1138 deletions

File tree

extension/android/BUCK

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ non_fbcode_target(_kind = fb_android_library,
4747
name = "executorch_llama",
4848
warnings_as_errors = False,
4949
srcs = [
50-
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmCallback.java",
51-
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmGenerationConfig.java",
52-
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmModule.java",
53-
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmModuleConfig.java",
50+
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmCallback.kt",
51+
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmGenerationConfig.kt",
52+
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmModule.kt",
53+
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmModuleConfig.kt",
5454
],
5555
autoglob = False,
56-
language = "JAVA",
56+
language = "KOTLIN",
5757
deps = [
5858
":executorch",
5959
"//fbandroid/java/com/facebook/jni:jni",

extension/android/executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmCallback.java renamed to extension/android/executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmCallback.kt

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,42 @@
66
* LICENSE file in the root directory of this source tree.
77
*/
88

9-
package org.pytorch.executorch.extension.llm;
9+
package org.pytorch.executorch.extension.llm
1010

11-
import com.facebook.jni.annotations.DoNotStrip;
12-
import org.pytorch.executorch.annotations.Experimental;
11+
import com.facebook.jni.annotations.DoNotStrip
12+
import org.pytorch.executorch.annotations.Experimental
1313

1414
/**
15-
* Callback interface for Llama model. Users can implement this interface to receive the generated
15+
* Callback interface for Llm model. Users can implement this interface to receive the generated
1616
* tokens and statistics.
1717
*
18-
* <p>Warning: These APIs are experimental and subject to change without notice
18+
* Warning: These APIs are experimental and subject to change without notice
1919
*/
2020
@Experimental
21-
public interface LlmCallback {
21+
interface LlmCallback {
2222
/**
2323
* Called when a new result is available from JNI. Users will keep getting onResult() invocations
2424
* until generate() finishes.
2525
*
2626
* @param result Last generated token
2727
*/
28-
@DoNotStrip
29-
public void onResult(String result);
28+
@DoNotStrip fun onResult(result: String)
3029

3130
/**
3231
* Called when the statistics for the generate() is available.
3332
*
34-
* <p>The result will be a JSON string. See extension/llm/stats.h for the field definitions.
33+
* The result will be a JSON string. See extension/llm/stats.h for the field definitions.
3534
*
3635
* @param stats JSON string containing the statistics for the generate()
3736
*/
38-
@DoNotStrip
39-
default void onStats(String stats) {}
37+
@DoNotStrip fun onStats(stats: String) {}
4038

4139
/**
4240
* Called when an error occurs during generate().
4341
*
44-
* @param errorCode Error code from the ExecuTorch runtime (see {@link
45-
* org.pytorch.executorch.ExecutorchRuntimeException})
42+
* @param errorCode Error code from the ExecuTorch runtime (see
43+
* [org.pytorch.executorch.ExecutorchRuntimeException])
4644
* @param message Human-readable error description
4745
*/
48-
@DoNotStrip
49-
default void onError(int errorCode, String message) {}
46+
@DoNotStrip fun onError(errorCode: Int, message: String) {}
5047
}

extension/android/executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmGenerationConfig.java

Lines changed: 0 additions & 198 deletions
This file was deleted.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
package org.pytorch.executorch.extension.llm
10+
11+
/**
12+
* Configuration class for controlling text generation parameters in LLM operations.
13+
*
14+
* This class provides settings for text generation behavior including output formatting, generation
15+
* limits, and sampling parameters. Instances should be created using the [create] method and the
16+
* fluent builder pattern.
17+
*/
18+
class LlmGenerationConfig
19+
private constructor(
20+
@get:JvmName("isEcho") val echo: Boolean,
21+
val maxNewTokens: Int,
22+
@get:JvmName("isWarming") val warming: Boolean,
23+
val seqLen: Int,
24+
val temperature: Float,
25+
val numBos: Int,
26+
val numEos: Int,
27+
) {
28+
29+
companion object {
30+
/**
31+
* Creates a new Builder instance for constructing generation configurations.
32+
*
33+
* @return a new Builder with default configuration values
34+
*/
35+
@JvmStatic fun create(): Builder = Builder()
36+
}
37+
38+
/**
39+
* Builder class for constructing LlmGenerationConfig instances.
40+
*
41+
* Provides a fluent interface for configuring generation parameters with sensible defaults. All
42+
* methods return the builder instance to enable method chaining.
43+
*/
44+
class Builder internal constructor() {
45+
private var echo: Boolean = true
46+
private var maxNewTokens: Int = -1
47+
private var warming: Boolean = false
48+
private var seqLen: Int = -1
49+
private var temperature: Float = 0.8f
50+
private var numBos: Int = 0
51+
private var numEos: Int = 0
52+
53+
/** Sets whether to include the input prompt in the generated output. */
54+
fun echo(echo: Boolean): Builder = apply { this.echo = echo }
55+
56+
/** Sets the maximum number of new tokens to generate. */
57+
fun maxNewTokens(maxNewTokens: Int): Builder = apply { this.maxNewTokens = maxNewTokens }
58+
59+
/** Enables or disables model warming. */
60+
fun warming(warming: Boolean): Builder = apply { this.warming = warming }
61+
62+
/** Sets the maximum sequence length for generation. */
63+
fun seqLen(seqLen: Int): Builder = apply { this.seqLen = seqLen }
64+
65+
/** Sets the temperature for random sampling. */
66+
fun temperature(temperature: Float): Builder = apply { this.temperature = temperature }
67+
68+
/** Sets the number of BOS tokens to prepend. */
69+
fun numBos(numBos: Int): Builder = apply { this.numBos = numBos }
70+
71+
/** Sets the number of EOS tokens to append. */
72+
fun numEos(numEos: Int): Builder = apply { this.numEos = numEos }
73+
74+
/** Constructs the LlmGenerationConfig instance with the configured parameters. */
75+
fun build(): LlmGenerationConfig =
76+
LlmGenerationConfig(echo, maxNewTokens, warming, seqLen, temperature, numBos, numEos)
77+
}
78+
}

0 commit comments

Comments
 (0)