-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: sort out inference code after refactor for finetune #9
base: main
Are you sure you want to change the base?
Changes from 3 commits
2021be3
d8400f7
cc56e62
fe63f42
bef2da1
4497071
59e7d31
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import {ethers} from 'ethers' | ||
import {createZGComputeNetworkBroker} from './src.ts' | ||
import OpenAI from 'openai' | ||
|
||
async function main() { | ||
const provider = new ethers.JsonRpcProvider('http://127.0.0.1:8545') | ||
|
||
// Step 1: Create a wallet with a private key | ||
const privateKey = | ||
'59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d' | ||
const wallet = new ethers.Wallet(privateKey, provider) | ||
|
||
// Step 2: Initialize the broker | ||
try { | ||
const broker = await createZGComputeNetworkBroker( | ||
wallet, | ||
'0x8A791620dd6260079BF849Dc5567aDC3F2FdC318', | ||
'0x0165878A594ca255338adfa4d48449f69242Eb8F', | ||
'0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0' | ||
) | ||
|
||
// List available services | ||
console.log('Listing available services...') | ||
const services = await broker.inference.listService() | ||
services.forEach((service: any) => { | ||
console.log( | ||
`Service: ${service.name}, Provider: ${service.provider}, Type: ${service.serviceType}, Model: ${service.model}, URL: ${service.url}, verifiability: ${service.verifiability}` | ||
) | ||
}) | ||
|
||
// Select a service | ||
const service = await broker.inference.getService("test") | ||
|
||
const providerAddress = service.provider; | ||
console.log("provider address is ", providerAddress) | ||
// create ledger | ||
// await broker.ledger.addLedger(0.001) | ||
// console.log('Creating ledger successfully.') | ||
|
||
// deposit fund | ||
// const depositAmount = 0.01 | ||
// await broker.ledger.depositFund(depositAmount) | ||
// console.log('Depositing funds...') | ||
|
||
// get ledger | ||
const ledger = await broker.ledger.getAllLedgers() | ||
console.log('Get ledger with fund ', ledger[0].totalBalance) | ||
|
||
// Step 5: Use the Provider's Services | ||
console.log('Processing a request...') | ||
const serviceName = service.name | ||
const content = 'hello world' | ||
|
||
await broker.inference.settleFee( | ||
providerAddress, | ||
serviceName, | ||
0.0000000008 | ||
) | ||
|
||
// Step 5.1: Get the request metadata | ||
const {endpoint, model} = | ||
await broker.inference.getServiceMetadata( | ||
providerAddress, | ||
serviceName | ||
) | ||
|
||
// Get the request headers | ||
const headers = await broker.inference.getRequestHeaders( | ||
providerAddress, | ||
serviceName, | ||
content | ||
) | ||
|
||
// Send a request to the service | ||
const openai = new OpenAI({ | ||
baseURL: endpoint, | ||
apiKey: '', | ||
}) | ||
const completion = await openai.chat.completions.create( | ||
{ | ||
messages: [{role: 'system', content}], | ||
model: model, | ||
// @ts-expect-error guided_json is not yet public | ||
guided_json: jsonSchema, | ||
}, | ||
{ | ||
headers: { | ||
...headers, | ||
}, | ||
} | ||
) | ||
|
||
const receivedContent = completion.choices[0].message.content | ||
const chatID = completion.id | ||
if (!receivedContent) { | ||
throw new Error('No content received.') | ||
} | ||
console.log('Response:', receivedContent) | ||
|
||
// Step 7: Process the response | ||
console.log('Processing a response...') | ||
const isValid = await broker.inference.processResponse( | ||
providerAddress, | ||
serviceName, | ||
receivedContent, | ||
chatID | ||
) | ||
console.log(`Response validity: ${isValid ? 'Valid' : 'Invalid'}`) | ||
|
||
// retrieve fund from all inference accounts. | ||
await broker.inference.retrieveFund() | ||
console.log("Closing the service...") | ||
} catch (error) { | ||
console.error('Error during execution:', error) | ||
} | ||
} | ||
|
||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import { ServingRequestHeaders } from './request' | |
import { decryptData, getNonce, strToPrivateKey } from '../../common/utils' | ||
import { PackedPrivkey, Request, signData } from '../../common/settle-signer' | ||
import { Cache, CacheValueTypeEnum } from '../storage' | ||
import {LedgerBroker} from "../../ledger"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove |
||
|
||
export abstract class ZGServingUserBrokerBase { | ||
protected contract: InferenceServingContract | ||
|
@@ -172,10 +173,21 @@ export abstract class ZGServingUserBrokerBase { | |
} | ||
} | ||
|
||
private async calculateInputFees(extractor: Extractor, content: string) { | ||
async calculateInputFees(extractor: Extractor, content: string) { | ||
const svc = await extractor.getSvcInfo() | ||
const inputCount = await extractor.getInputCount(content) | ||
const inputFee = BigInt(inputCount) * svc.inputPrice | ||
return inputFee | ||
} | ||
|
||
async updateCachedFee(provide: string, fee: bigint) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To prevent duplication, the cache key should be formatted as ${providerAddress}_${serviceName}_cachedFee. |
||
try { | ||
const curFee = await this.cache.getItemOr(provide, BigInt(0)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. doesn't need getItemOr but just use |
||
await this.cache.setItem(provide, BigInt(curFee) + fee, | ||
1 * 60 * 1000, CacheValueTypeEnum.Service) | ||
} catch (error) { | ||
throw error | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,12 +1,13 @@ | ||||||
import { AccountStructOutput, InferenceServingContract } from '../contract' | ||||||
import { JsonRpcSigner, Wallet } from 'ethers' | ||||||
import { RequestProcessor } from './request' | ||||||
import { ResponseProcessor } from './response' | ||||||
import { Verifier } from './verifier' | ||||||
import { AccountProcessor } from './account' | ||||||
import { ModelProcessor } from './model' | ||||||
import { Metadata } from '../../common/storage' | ||||||
import { Cache } from '../storage' | ||||||
import {AccountStructOutput, InferenceServingContract, ServiceStructOutput} from '../contract' | ||||||
import {AddressLike, JsonRpcSigner, Wallet} from 'ethers' | ||||||
import {RequestProcessor} from './request' | ||||||
import {ResponseProcessor} from './response' | ||||||
import {Verifier} from './verifier' | ||||||
import {AccountProcessor} from './account' | ||||||
import {ModelProcessor} from './model' | ||||||
import {Metadata} from '../../common/storage' | ||||||
import {Cache} from '../storage' | ||||||
import {LedgerBroker} from '../../ledger' | ||||||
|
||||||
export class InferenceBroker { | ||||||
public requestProcessor!: RequestProcessor | ||||||
|
@@ -17,10 +18,12 @@ export class InferenceBroker { | |||||
|
||||||
private signer: JsonRpcSigner | Wallet | ||||||
private contractAddress: string | ||||||
private ledger: LedgerBroker | ||||||
|
||||||
constructor(signer: JsonRpcSigner | Wallet, contractAddress: string) { | ||||||
constructor(signer: JsonRpcSigner | Wallet, contractAddress: string, ledger: LedgerBroker) { | ||||||
this.signer = signer | ||||||
this.contractAddress = contractAddress | ||||||
this.ledger = ledger | ||||||
} | ||||||
|
||||||
async initialize() { | ||||||
|
@@ -37,12 +40,8 @@ export class InferenceBroker { | |||||
) | ||||||
const metadata = new Metadata() | ||||||
const cache = new Cache() | ||||||
this.requestProcessor = new RequestProcessor(contract, metadata, cache) | ||||||
this.responseProcessor = new ResponseProcessor( | ||||||
contract, | ||||||
metadata, | ||||||
cache | ||||||
) | ||||||
this.requestProcessor = new RequestProcessor(contract, metadata, cache, this.ledger) | ||||||
this.responseProcessor = new ResponseProcessor(contract, metadata, cache, this.ledger) | ||||||
this.accountProcessor = new AccountProcessor(contract, metadata, cache) | ||||||
this.modelProcessor = new ModelProcessor(contract, metadata, cache) | ||||||
this.verifier = new Verifier(contract, metadata, cache) | ||||||
|
@@ -62,23 +61,9 @@ export class InferenceBroker { | |||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* Adds a new account to the contract. | ||||||
* | ||||||
* @param {string} providerAddress - The address of the provider for whom the account is being created. | ||||||
* @param {number} balance - The initial balance to be assigned to the new account. Units are in A0GI. | ||||||
* | ||||||
* @throws An error if the account creation fails. | ||||||
* | ||||||
* @remarks | ||||||
* When creating an account, a key pair is also created to sign the request. | ||||||
*/ | ||||||
public addAccount = async (providerAddress: string, balance: number) => { | ||||||
public getService = async (svcName: string): Promise<ServiceStructOutput> => { | ||||||
Ravenyjh marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
try { | ||||||
return await this.accountProcessor.addAccount( | ||||||
providerAddress, | ||||||
balance | ||||||
) | ||||||
return await this.modelProcessor.getService(svcName) | ||||||
} catch (error) { | ||||||
throw error | ||||||
} | ||||||
|
@@ -103,21 +88,6 @@ export class InferenceBroker { | |||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* Deposits a specified amount of funds into the given account. | ||||||
* | ||||||
* @param {string} account - The account identifier where the funds will be deposited. | ||||||
* @param {string} amount - The amount of funds to be deposited. Units are in A0GI. | ||||||
* @throws An error if the deposit fails. | ||||||
*/ | ||||||
public depositFund = async (account: string, amount: number) => { | ||||||
try { | ||||||
return await this.accountProcessor.depositFund(account, amount) | ||||||
} catch (error) { | ||||||
throw error | ||||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* Generates request metadata for the provider service. | ||||||
* Includes: | ||||||
|
@@ -356,6 +326,25 @@ export class InferenceBroker { | |||||
throw error | ||||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* retrive fund from all inference account back to ledger | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
*/ | ||||||
public retrieveFund = async () => { | ||||||
try { | ||||||
const ledger = await this.ledger.getLedger() | ||||||
let retrieveProviders = [] | ||||||
for (const provider of ledger.inferenceProviders) { | ||||||
const acc = await this.getAccount(provider) | ||||||
if (acc.balance > 0) { | ||||||
retrieveProviders.push(provider) | ||||||
} | ||||||
} | ||||||
await this.ledger.retrieveFund(retrieveProviders, "inference") | ||||||
} catch (error) { | ||||||
throw error | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
|
@@ -370,9 +359,10 @@ export class InferenceBroker { | |||||
*/ | ||||||
export async function createInferenceBroker( | ||||||
signer: JsonRpcSigner | Wallet, | ||||||
contractAddress = '' | ||||||
contractAddress = '', | ||||||
ledger: LedgerBroker | ||||||
): Promise<InferenceBroker> { | ||||||
const broker = new InferenceBroker(signer, contractAddress) | ||||||
const broker = new InferenceBroker(signer, contractAddress, ledger) | ||||||
try { | ||||||
await broker.initialize() | ||||||
return broker | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After local testing, integrate the content into src.ts/example/inference.md. There's no need to add another file.